Code

Split SPCanvasItem and SPCanvasGroup to individual .h files. Pruned forward header.
[inkscape.git] / src / libcroco / cr-style.c
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3 /*
4  * This file is part of The Croco Library
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2.1 of 
8  * the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the 
17  * GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  *
22  * Author: Dodji Seketeli.
23  * see COPYRIGTHS file for copyright information
24  */
26 #include <string.h>
27 #include "cr-style.h"
29 /**
30  *@file
31  *The definition of the #CRStyle class.
32  */
34 /**
35  *A property ID.
36  *Each supported css property has an ID which is
37  *an entry into a property "population" jump table.
38  *each entry of the property population jump table
39  *contains code to tranform the literal form of
40  *a property value into a strongly typed value.
41  */
42 enum CRPropertyID {
43         PROP_ID_NOT_KNOWN = 0,
44         PROP_ID_PADDING_TOP,
45         PROP_ID_PADDING_RIGHT,
46         PROP_ID_PADDING_BOTTOM,
47         PROP_ID_PADDING_LEFT,
48         PROP_ID_PADDING,
49         PROP_ID_BORDER_TOP_WIDTH,
50         PROP_ID_BORDER_RIGHT_WIDTH,
51         PROP_ID_BORDER_BOTTOM_WIDTH,
52         PROP_ID_BORDER_LEFT_WIDTH,
53         PROP_ID_BORDER_WIDTH,
54         PROP_ID_BORDER_TOP_STYLE,
55         PROP_ID_BORDER_RIGHT_STYLE,
56         PROP_ID_BORDER_BOTTOM_STYLE,
57         PROP_ID_BORDER_LEFT_STYLE,
58         PROP_ID_BORDER_STYLE,
59         PROP_ID_BORDER_TOP_COLOR,
60         PROP_ID_BORDER_RIGHT_COLOR,
61         PROP_ID_BORDER_BOTTOM_COLOR,
62         PROP_ID_BORDER_LEFT_COLOR,
63         PROP_ID_BORDER_TOP,
64         PROP_ID_BORDER_RIGHT,
65         PROP_ID_BORDER_BOTTOM,
66         PROP_ID_BORDER_LEFT,
67         PROP_ID_BORDER,
68         PROP_ID_MARGIN_TOP,
69         PROP_ID_MARGIN_RIGHT,
70         PROP_ID_MARGIN_BOTTOM,
71         PROP_ID_MARGIN_LEFT,
72         PROP_ID_MARGIN,
73         PROP_ID_DISPLAY,
74         PROP_ID_POSITION,
75         PROP_ID_TOP,
76         PROP_ID_RIGHT,
77         PROP_ID_BOTTOM,
78         PROP_ID_LEFT,
79         PROP_ID_FLOAT,
80         PROP_ID_WIDTH,
81         PROP_ID_COLOR,
82         PROP_ID_BACKGROUND_COLOR,
83         PROP_ID_FONT_FAMILY,
84         PROP_ID_FONT_SIZE,
85         PROP_ID_FONT_STYLE,
86         PROP_ID_FONT_WEIGHT,
87         PROP_ID_WHITE_SPACE,
88         /*should be the last one. */
89         NB_PROP_IDS
90 };
92 typedef struct _CRPropertyDesc CRPropertyDesc;
94 struct _CRPropertyDesc {
95         const gchar *name;
96         enum CRPropertyID prop_id;
97 };
99 static CRPropertyDesc gv_prop_table[] = {
100         {"padding-top", PROP_ID_PADDING_TOP},
101         {"padding-right", PROP_ID_PADDING_RIGHT},
102         {"padding-bottom", PROP_ID_PADDING_BOTTOM},
103         {"padding-left", PROP_ID_PADDING_LEFT},
104         {"padding", PROP_ID_PADDING},
105         {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
106         {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
107         {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
108         {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
109         {"border-width", PROP_ID_BORDER_WIDTH},
110         {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
111         {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
112         {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
113         {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
114         {"border-style", PROP_ID_BORDER_STYLE},
115         {"border-top", PROP_ID_BORDER_TOP},
116         {"border-right", PROP_ID_BORDER_RIGHT},
117         {"border-bottom", PROP_ID_BORDER_BOTTOM},
118         {"border-left", PROP_ID_BORDER_LEFT},
119         {"border", PROP_ID_BORDER},
120         {"margin-top", PROP_ID_MARGIN_TOP},
121         {"margin-right", PROP_ID_MARGIN_RIGHT},
122         {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
123         {"margin-left", PROP_ID_MARGIN_LEFT},
124         {"margin", PROP_ID_MARGIN},
125         {"display", PROP_ID_DISPLAY},
126         {"position", PROP_ID_POSITION},
127         {"top", PROP_ID_TOP},
128         {"right", PROP_ID_RIGHT},
129         {"bottom", PROP_ID_BOTTOM},
130         {"left", PROP_ID_LEFT},
131         {"float", PROP_ID_FLOAT},
132         {"width", PROP_ID_WIDTH},
133         {"color", PROP_ID_COLOR},
134         {"border-top-color", PROP_ID_BORDER_TOP_COLOR},
135         {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR},
136         {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR},
137         {"border-left-color", PROP_ID_BORDER_LEFT_COLOR},
138         {"background-color", PROP_ID_BACKGROUND_COLOR},
139         {"font-family", PROP_ID_FONT_FAMILY},
140         {"font-size", PROP_ID_FONT_SIZE},
141         {"font-style", PROP_ID_FONT_STYLE},
142         {"font-weight", PROP_ID_FONT_WEIGHT},
143             {"white-space", PROP_ID_WHITE_SPACE},
144         /*must be the last one */
145         {NULL, (enum CRPropertyID)0}
146 };
148 /**
149  *A the key/value pair of this hash table
150  *are:
151  *key => name of the the css propertie found in gv_prop_table
152  *value => matching property id found in gv_prop_table.
153  *So this hash table is here just to retrieval of a property id
154  *from a property name.
155  */
156 static GHashTable *gv_prop_hash = NULL;
158 /**
159  *incremented by each new instance of #CRStyle
160  *and decremented at the it destroy time.
161  *When this reaches zero, gv_prop_hash is destroyed.
162  */
163 static gulong gv_prop_hash_ref_count = 0;
165 struct CRNumPropEnumDumpInfo {
166         enum CRNumProp code;
167         const gchar *str;
168 };
170 static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
171         {NUM_PROP_TOP, "top"},
172         {NUM_PROP_RIGHT, "right"},
173         {NUM_PROP_BOTTOM, "bottom"},
174         {NUM_PROP_LEFT, "left"},
175         {NUM_PROP_PADDING_TOP, "padding-top"},
176         {NUM_PROP_PADDING_RIGHT, "padding-right"},
177         {NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
178         {NUM_PROP_PADDING_LEFT, "padding-left"},
179         {NUM_PROP_BORDER_TOP, "border-top"},
180         {NUM_PROP_BORDER_RIGHT, "border-right"},
181         {NUM_PROP_BORDER_BOTTOM, "border-bottom"},
182         {NUM_PROP_BORDER_LEFT, "border-left"},
183         {NUM_PROP_MARGIN_TOP, "margin-top"},
184         {NUM_PROP_MARGIN_RIGHT, "margin-right"},
185         {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
186         {NUM_PROP_MARGIN_LEFT, "margin-left"},
187         {NUM_PROP_WIDTH, "width"},
188         {(enum CRNumProp)0, NULL}
189 };
191 struct CRRgbPropEnumDumpInfo {
192         enum CRRgbProp code;
193         const gchar *str;
194 };
196 static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
197         {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
198         {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
199         {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
200         {RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
201         {RGB_PROP_COLOR, "color"},
202         {RGB_PROP_BACKGROUND_COLOR, "background-color"},
203         {(enum CRRgbProp)0, NULL}
204 };
206 struct CRBorderStylePropEnumDumpInfo {
207         enum CRBorderStyleProp code;
208         const gchar *str;
210 };
212 static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
213         = {
214         {BORDER_STYLE_PROP_TOP, "border-style-top"},
215         {BORDER_STYLE_PROP_RIGHT, "border-style-right"},
216         {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
217         {BORDER_STYLE_PROP_LEFT, "border-style-left"},
218         {(enum CRBorderStyleProp)0, NULL}
219 };
221 static enum CRStatus
222   cr_style_init_properties (void);
224 enum CRDirection {
225         DIR_TOP = 0,
226         DIR_RIGHT,
227         DIR_BOTTOM,
228         DIR_LEFT,
230         /*must be the last one */
231         NB_DIRS
232 };
234 static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
236 static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
238 static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
239                                                       a_code);
241 static enum CRStatus
242 set_prop_padding_x_from_value (CRStyle * a_style,
243                                  CRTerm * a_value, enum CRDirection a_dir);
245 static enum CRStatus
246 set_prop_border_x_width_from_value (CRStyle * a_style,
247                                     CRTerm * a_value,
248                                     enum CRDirection a_dir);
249 static enum CRStatus
250 set_prop_border_width_from_value (CRStyle *a_style,
251                                   CRTerm *a_value) ;
253 static enum CRStatus
254 set_prop_border_x_style_from_value (CRStyle * a_style,
255                                     CRTerm * a_value,
256                                     enum CRDirection a_dir);
257 static enum CRStatus
258 set_prop_border_style_from_value (CRStyle *a_style,
259                                   CRTerm *a_value) ;
261 static enum CRStatus
262 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
263                                 enum CRDirection a_dir);
265 static enum CRStatus
266 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
268 static enum CRStatus
269 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
271 static enum CRStatus
272 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
273                          enum CRDirection a_dir);
275 static enum CRStatus
276 set_prop_float (CRStyle * a_style, CRTerm * a_value);
278 static enum CRStatus
279 set_prop_width (CRStyle * a_style, CRTerm * a_value);
281 static enum CRStatus
282 set_prop_color (CRStyle * a_style, CRTerm * a_value);
284 static enum CRStatus
285 set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
287 static enum CRStatus
288 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
289                                       enum CRDirection a_dir);
291 static enum CRStatus
292 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
293                                 enum CRDirection a_dir);
295 static enum CRStatus
296 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
298 static enum CRStatus
299 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
301 static enum CRStatus
302 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
304 static enum CRStatus
305 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
307 static enum CRStatus
308 init_style_font_size_field (CRStyle * a_style);
310 static enum CRStatus
311 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
313 static enum CRStatus
314 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
316 static enum CRStatus
317 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
319 static const gchar *
320 num_prop_code_to_string (enum CRNumProp a_code)
322         int len = sizeof (gv_num_props_dump_infos) /
323                 sizeof (struct CRNumPropEnumDumpInfo);
324         if ((int)a_code >= len) {
325                 cr_utils_trace_info ("A field has been added "
326                                      "to 'enum CRNumProp' and no matching"
327                                      " entry has been "
328                                      "added to gv_num_prop_dump_infos table.\n"
329                                      "Please add the missing matching entry");
330                 return NULL;
331         }
332         if (gv_num_props_dump_infos[a_code].code != a_code) {
333                 cr_utils_trace_info ("mismatch between the order of fields in"
334                                      " 'enum CRNumProp' and "
335                                      "the order of entries in "
336                                      "the gv_num_prop_dump_infos table");
337                 return NULL;
338         }
339         return gv_num_props_dump_infos[a_code].str;
342 static const gchar *
343 rgb_prop_code_to_string (enum CRRgbProp a_code)
345         int len = sizeof (gv_rgb_props_dump_infos) /
346                 sizeof (struct CRRgbPropEnumDumpInfo);
348         if ((int)a_code >= len) {
349                 cr_utils_trace_info ("A field has been added "
350                                      "to 'enum CRRgbProp' and no matching"
351                                      " entry has been "
352                                      "added to gv_rgb_prop_dump_infos table.\n"
353                                      "Please add the missing matching entry");
354                 return NULL;
355         }
356         if (gv_rgb_props_dump_infos[a_code].code != a_code) {
357                 cr_utils_trace_info ("mismatch between the order of fields in"
358                                      " 'enum CRRgbProp' and "
359                                      "the order of entries in "
360                                      "the gv_rgb_props_dump_infos table");
361                 return NULL;
362         }
363         return gv_rgb_props_dump_infos[a_code].str;
366 static const gchar *
367 border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
369         int len = sizeof (gv_border_style_props_dump_infos) /
370                 sizeof (struct CRBorderStylePropEnumDumpInfo);
372         if ((int)a_code >= len) {
373                 cr_utils_trace_info ("A field has been added "
374                                      "to 'enum CRBorderStyleProp' and no matching"
375                                      " entry has been "
376                                      "added to gv_border_style_prop_dump_infos table.\n"
377                                      "Please add the missing matching entry");
378                 return NULL;
379         }
380         if (gv_border_style_props_dump_infos[a_code].code != a_code) {
381                 cr_utils_trace_info ("mismatch between the order of fields in"
382                                      " 'enum CRBorderStyleProp' and "
383                                      "the order of entries in "
384                                      "the gv_border_style_props_dump_infos table");
385                 return NULL;
386         }
387         return gv_border_style_props_dump_infos[a_code].str;
390 static enum CRStatus
391 cr_style_init_properties (void)
394         if (!gv_prop_hash) {
395                 gulong i = 0;
397                 gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal);
398                 if (!gv_prop_hash) {
399                         cr_utils_trace_info ("Out of memory");
400                         return CR_ERROR;
401                 }
403                 /*load gv_prop_hash from gv_prop_table */
404                 for (i = 0; gv_prop_table[i].name; i++) {
405                         g_hash_table_insert
406                                 (gv_prop_hash,
407                                  (gpointer) gv_prop_table[i].name,
408                                  GINT_TO_POINTER (gv_prop_table[i].prop_id));
409                 }
410         }
412         return CR_OK;
415 static enum CRPropertyID
416 cr_style_get_prop_id (const guchar * a_prop)
418         gpointer *raw_id = NULL;
420         if (!gv_prop_hash) {
421                 cr_style_init_properties ();
422         }
424         raw_id = (gpointer *)g_hash_table_lookup (gv_prop_hash, a_prop);
425         if (!raw_id) {
426                 return PROP_ID_NOT_KNOWN;
427         }
428         return (enum CRPropertyID)GPOINTER_TO_INT (raw_id);
431 static enum CRStatus
432 set_prop_padding_x_from_value (CRStyle * a_style,
433                                CRTerm * a_value, enum CRDirection a_dir)
435         enum CRStatus status = CR_OK;
436         CRNum *num_val = NULL;
438         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
440         if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
441                 return CR_BAD_PARAM_ERROR;
443         switch (a_dir) {
444         case DIR_TOP:
445                 num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
446                 break;
448         case DIR_RIGHT:
449                 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
450                 break;
452         case DIR_BOTTOM:
453                 num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
454                 break;
456         case DIR_LEFT:
457                 num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
458                 break;
460         default:
461                 return CR_BAD_PARAM_ERROR;
462         }
464         if (a_value->type == TERM_IDENT) {
465                 if (a_value->content.str
466                     && a_value->content.str->stryng
467                     && a_value->content.str->stryng->str
468                     && !strncmp ("inherit",
469                                  a_value->content.str->stryng->str,
470                                  sizeof ("inherit")-1)) {
471                         status = cr_num_set (num_val, 0.0, NUM_INHERIT);
472                         return CR_OK;
473                 } else
474                         return CR_UNKNOWN_TYPE_ERROR;
475         }
477         g_return_val_if_fail (a_value->type == TERM_NUMBER
478                               && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
480         switch (a_value->content.num->type) {
481         case NUM_LENGTH_EM:
482         case NUM_LENGTH_EX:
483         case NUM_LENGTH_PX:
484         case NUM_LENGTH_IN:
485         case NUM_LENGTH_CM:
486         case NUM_LENGTH_MM:
487         case NUM_LENGTH_PT:
488         case NUM_LENGTH_PC:
489         case NUM_PERCENTAGE:
490                 status = cr_num_copy (num_val, a_value->content.num);
491                 break;
492         default:
493                 status = CR_UNKNOWN_TYPE_ERROR;
494                 break;
495         }
497         return status;
500 static enum CRStatus
501 set_prop_border_x_width_from_value (CRStyle * a_style,
502                                     CRTerm * a_value, 
503                                     enum CRDirection a_dir)
505         enum CRStatus status = CR_OK;
506         CRNum *num_val = NULL;
508         g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
510         switch (a_dir) {
511         case DIR_TOP:
512                 num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
513                 break;
515         case DIR_RIGHT:
516                 num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
517                 break;
519         case DIR_BOTTOM:
520                 num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
521                 break;
523         case DIR_LEFT:
524                 num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
525                 break;
527         default:
528                 return CR_BAD_PARAM_ERROR;
529                 break;
530         }
532         if (a_value->type == TERM_IDENT) {
533                 if (a_value->content.str 
534                     && a_value->content.str->stryng
535                     && a_value->content.str->stryng->str) {
536                         if (!strncmp ("thin",
537                                       a_value->content.str->stryng->str,
538                                       sizeof ("thin")-1)) {
539                                 cr_num_set (num_val, BORDER_THIN,
540                                             NUM_LENGTH_PX);
541                         } else if (!strncmp 
542                                    ("medium",
543                                     a_value->content.str->stryng->str,
544                                              sizeof ("medium")-1)) {
545                                 cr_num_set (num_val, BORDER_MEDIUM,
546                                             NUM_LENGTH_PX);
547                         } else if (!strncmp ("thick",
548                                              a_value->content.str->stryng->str,
549                                              sizeof ("thick")-1)) {
550                                 cr_num_set (num_val, BORDER_THICK,
551                                             NUM_LENGTH_PX);
552                         } else {
553                                 return CR_UNKNOWN_TYPE_ERROR;
554                         }
555                 }
556         } else if (a_value->type == TERM_NUMBER) {
557                 if (a_value->content.num) {
558                         cr_num_copy (num_val, a_value->content.num);
559                 }
560         } else if (a_value->type != TERM_NUMBER
561                    || a_value->content.num == NULL) {
562                 return CR_UNKNOWN_TYPE_ERROR;
563         }
565         return status;
568 static enum CRStatus
569 set_prop_border_width_from_value (CRStyle *a_style,
570                                   CRTerm *a_value)
572         g_return_val_if_fail (a_style && a_value,
573                               CR_BAD_PARAM_ERROR) ;
574         CRTerm *cur_term = a_value ;
576         if (!cur_term)
577                 return CR_ERROR ;
579         int dir;
580         for (dir = (int) DIR_TOP ; dir < (int)NB_DIRS ; dir++) {
581                  enum CRDirection direction = (enum CRDirection)dir;
582                  set_prop_border_x_width_from_value (a_style, 
583                                                     cur_term,
584                                                     direction) ;
585         }
587         cur_term = cur_term->next ;
588         if (!cur_term)
589                 return CR_OK ;
590         set_prop_border_x_width_from_value (a_style, cur_term,
591                                             DIR_RIGHT) ;
592         set_prop_border_x_width_from_value (a_style, cur_term,
593                                             DIR_LEFT) ;
595         cur_term = cur_term->next ;
596         if (!cur_term)
597                 return CR_OK ;
598         set_prop_border_x_width_from_value (a_style, cur_term,
599                                             DIR_BOTTOM) ;
601         cur_term = cur_term->next ;
602         if (!cur_term)
603                 return CR_OK ;
604         set_prop_border_x_width_from_value (a_style, cur_term,
605                                             DIR_LEFT) ;
607         return CR_OK ;
610 static enum CRStatus
611 set_prop_border_x_style_from_value (CRStyle * a_style,
612                                     CRTerm * a_value, enum CRDirection a_dir)
614         enum CRStatus status = CR_OK;
615         enum CRBorderStyle *border_style_ptr = NULL;
617         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
619         switch (a_dir) {
620         case DIR_TOP:
621                 border_style_ptr = &a_style->
622                         border_style_props[BORDER_STYLE_PROP_TOP];
623                 break;
625         case DIR_RIGHT:
626                 border_style_ptr =
627                         &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
628                 break;
630         case DIR_BOTTOM:
631                 border_style_ptr = &a_style->
632                         border_style_props[BORDER_STYLE_PROP_BOTTOM];
633                 break;
635         case DIR_LEFT:
636                 border_style_ptr = &a_style->
637                         border_style_props[BORDER_STYLE_PROP_LEFT];
638                 break;
640         default:
641                 break;
642         }
644         if (a_value->type != TERM_IDENT || !a_value->content.str) {
645                 return CR_UNKNOWN_TYPE_ERROR;
646         }
648         if (!strncmp ("none", 
649                       a_value->content.str->stryng->str, 
650                       sizeof ("none")-1)) {
651                 *border_style_ptr = BORDER_STYLE_NONE;
652         } else if (!strncmp ("hidden",
653                              a_value->content.str->stryng->str, 
654                              sizeof ("hidden")-1)) {
655                 *border_style_ptr = BORDER_STYLE_HIDDEN;
656         } else if (!strncmp ("dotted",
657                              a_value->content.str->stryng->str, 
658                              sizeof ("dotted")-1)) {
659                 *border_style_ptr = BORDER_STYLE_DOTTED;
660         } else if (!strncmp ("dashed",
661                              a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
662                 *border_style_ptr = BORDER_STYLE_DASHED;
663         } else if (!strncmp ("solid",
664                              a_value->content.str->stryng->str, sizeof ("solid")-1)) {
665                 *border_style_ptr = BORDER_STYLE_SOLID;
666         } else if (!strncmp ("double",
667                              a_value->content.str->stryng->str, sizeof ("double")-1)) {
668                 *border_style_ptr = BORDER_STYLE_DOUBLE;
669         } else if (!strncmp ("groove",
670                              a_value->content.str->stryng->str, sizeof ("groove")-1)) {
671                 *border_style_ptr = BORDER_STYLE_GROOVE;
672         } else if (!strncmp ("ridge",
673                              a_value->content.str->stryng->str, 
674                              sizeof ("ridge")-1)) {
675                 *border_style_ptr = BORDER_STYLE_RIDGE;
676         } else if (!strncmp ("inset",
677                              a_value->content.str->stryng->str, 
678                              sizeof ("inset")-1)) {
679                 *border_style_ptr = BORDER_STYLE_INSET;
680         } else if (!strncmp ("outset",
681                              a_value->content.str->stryng->str, 
682                              sizeof ("outset")-1)) {
683                 *border_style_ptr = BORDER_STYLE_OUTSET;
684         } else if (!strncmp ("inherit",
685                              a_value->content.str->stryng->str, 
686                              sizeof ("inherit")-1)) {
687                 *border_style_ptr = BORDER_STYLE_INHERIT;
688         } else {
689                 status = CR_UNKNOWN_TYPE_ERROR;
690         }
692         return status;
695 static enum CRStatus
696 set_prop_border_style_from_value (CRStyle *a_style,
697                                   CRTerm *a_value)
699         g_return_val_if_fail (a_style && a_value, 
700                               CR_BAD_PARAM_ERROR) ;
702         CRTerm *cur_term = a_value ;
703         if (!cur_term || cur_term->type != TERM_IDENT) {
704                 return CR_ERROR ;
705         }
706         
707         int dir;
708         for (dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++) { 
709                 enum CRDirection direction = (enum CRDirection)dir;
710                 set_prop_border_x_style_from_value (a_style, 
711                                                     cur_term,
712                                                     direction) ;
713         }
714         
715         cur_term = cur_term->next ;
716         if (!cur_term || cur_term->type != TERM_IDENT) {
717                 return CR_OK ;
718         }
719         
720         set_prop_border_x_style_from_value (a_style, cur_term, 
721                                             DIR_RIGHT) ;
722         set_prop_border_x_style_from_value (a_style, cur_term, 
723                                             DIR_LEFT) ;
725         cur_term = cur_term->next ;
726         if (!cur_term || cur_term->type != TERM_IDENT) {
727                 return CR_OK ;
728         }        
729         set_prop_border_x_style_from_value (a_style, cur_term,
730                                            DIR_BOTTOM) ;
731         
732         cur_term = cur_term->next ;
733         if (!cur_term || cur_term->type != TERM_IDENT) {
734                 return CR_OK ;
735         }
736         set_prop_border_x_style_from_value (a_style, cur_term,
737                                             DIR_LEFT) ;
738         return CR_OK ;
741 static enum CRStatus
742 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
743                               enum CRDirection a_dir)
745         enum CRStatus status = CR_OK;
746         CRNum *num_val = NULL;
748         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
750         switch (a_dir) {
751         case DIR_TOP:
752                 num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
753                 break;
755         case DIR_RIGHT:
756                 num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
757                 break;
759         case DIR_BOTTOM:
760                 num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
761                 break;
763         case DIR_LEFT:
764                 num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
765                 break;
767         default:
768                 break;
769         }
771         switch (a_value->type) {
772         case TERM_IDENT:
773                 if (a_value->content.str
774                     && a_value->content.str->stryng
775                     && a_value->content.str->stryng->str
776                     && !strcmp (a_value->content.str->stryng->str,
777                                  "inherit")) {
778                         status = cr_num_set (num_val, 0.0, NUM_INHERIT);
779                 } else if (a_value->content.str
780                            && a_value->content.str->stryng
781                            && !strcmp (a_value->content.str->stryng->str,
782                                         "auto")) {
783                         status = cr_num_set (num_val, 0.0, NUM_AUTO);
784                 } else {
785                         status = CR_UNKNOWN_TYPE_ERROR;
786                 }
787                 break ;
789         case TERM_NUMBER:
790                 status = cr_num_copy (num_val, a_value->content.num);
791                 break;
793         default:
794                 status = CR_UNKNOWN_TYPE_ERROR;
795                 break;
796         }
798         return status;
801 struct CRPropDisplayValPair {
802         const gchar *prop_name;
803         enum CRDisplayType type;
804 };
806 static enum CRStatus
807 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
809         static const struct CRPropDisplayValPair disp_vals_map[] = {
810                 {"none", DISPLAY_NONE},
811                 {"inline", DISPLAY_INLINE},
812                 {"block", DISPLAY_BLOCK},
813                 {"run-in", DISPLAY_RUN_IN},
814                 {"compact", DISPLAY_COMPACT},
815                 {"marker", DISPLAY_MARKER},
816                 {"table", DISPLAY_TABLE},
817                 {"inline-table", DISPLAY_INLINE_TABLE},
818                 {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
819                 {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
820                 {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
821                 {"table-row", DISPLAY_TABLE_ROW},
822                 {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
823                 {"table-column", DISPLAY_TABLE_COLUMN},
824                 {"table-cell", DISPLAY_TABLE_CELL},
825                 {"table-caption", DISPLAY_TABLE_CAPTION},
826                 {"inherit", DISPLAY_INHERIT},
827                 {NULL, DISPLAY_NONE}
828         };
830         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
832         switch (a_value->type) {
833         case TERM_IDENT:
834                 {
835                         int i = 0;
837                         if (!a_value->content.str
838                             || !a_value->content.str->stryng
839                             || !a_value->content.str->stryng->str)
840                                 break;
842                         for (i = 0; disp_vals_map[i].prop_name; i++) {
843                                 if (!strncmp 
844                                     (disp_vals_map[i].prop_name,
845                                      a_value->content.str->stryng->str,
846                                      strlen (disp_vals_map[i].prop_name))) {
847                                         a_style->display =
848                                                 disp_vals_map[i].type;
849                                         break;
850                                 }
851                         }
852                 }
853                 break;
855         default:
856                 break;
857         }
859         return CR_OK;
862 struct CRPropPositionValPair {
863         const gchar *name;
864         enum CRPositionType type;
865 };
867 static enum CRStatus
868 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
870         enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
871         static const struct CRPropPositionValPair position_vals_map[] = {
872                 {"static", POSITION_STATIC},
873                 {"relative", POSITION_RELATIVE},
874                 {"absolute", POSITION_ABSOLUTE},
875                 {"fixed", POSITION_FIXED},
876                 {"inherit", POSITION_INHERIT},
877                 {NULL, POSITION_STATIC}
878                 /*must alwas be the last one */
879         };
881         g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
883         switch (a_value->type) {
884         case TERM_IDENT:
885                 {
886                         int i = 0;
888                         if (!a_value->content.str
889                             || !a_value->content.str->stryng
890                             || !a_value->content.str->stryng->str)
891                                 break;
893                         for (i = 0; position_vals_map[i].name; i++) {
894                                 if (!strncmp (position_vals_map[i].name,
895                                               a_value->content.str->stryng->str,
896                                               strlen (position_vals_map[i].
897                                                       name))) {
898                                         a_style->position =
899                                                 position_vals_map[i].type;
900                                         status = CR_OK;
901                                         break;
902                                 }
903                         }
904                 }
905                 break;
907         default:
908                 break;
909         }
911         return CR_OK;
914 static enum CRStatus
915 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
916                        enum CRDirection a_dir)
918         CRNum *box_offset = NULL;
920         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
922         if (!(a_value->type == TERM_NUMBER)
923             && !(a_value->type == TERM_IDENT)) {
924                 return CR_UNKNOWN_PROP_VAL_ERROR;
925         }
927         switch (a_dir) {
928         case DIR_TOP:
929                 box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
930                 break;
932         case DIR_RIGHT:
933                 box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
934                 break;
936         case DIR_BOTTOM:
937                 box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
938                 break;
939         case DIR_LEFT:
940                 box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
941                 break;
943         default:
944                 break;
945         }
947         box_offset->type = NUM_AUTO;
949         if (a_value->type == TERM_NUMBER && a_value->content.num) {
950                 cr_num_copy (box_offset, a_value->content.num);
951         } else if (a_value->type == TERM_IDENT
952                    && a_value->content.str
953                    && a_value->content.str->stryng
954                    && a_value->content.str->stryng->str) {
955                 if (!strncmp ("inherit",
956                               a_value->content.str->stryng->str,
957                               sizeof ("inherit")-1)) {
958                         cr_num_set (box_offset, 0.0, NUM_INHERIT);
959                 } else if (!strncmp ("auto",
960                                      a_value->content.str->stryng->str,
961                                      sizeof ("auto")-1)) {
962                         box_offset->type = NUM_AUTO;
963                 }
964         }
966         return CR_OK;
969 static enum CRStatus
970 set_prop_float (CRStyle * a_style, CRTerm * a_value)
972         g_return_val_if_fail (a_style && a_value, 
973                               CR_BAD_PARAM_ERROR);
975         /*the default float type as specified by the css2 spec */
976         a_style->float_type = FLOAT_NONE;
978         if (a_value->type != TERM_IDENT 
979             || !a_value->content.str
980             || !a_value->content.str->stryng
981             || !a_value->content.str->stryng->str) { 
982                 /*unknow type, the float type is set to it's default value */
983                 return CR_OK;
984         }
986         if (!strncmp ("none", 
987                       a_value->content.str->stryng->str, 
988                       sizeof ("none")-1)) {
989                 a_style->float_type = FLOAT_NONE;
990         } else if (!strncmp ("left",
991                              a_value->content.str->stryng->str, 
992                              sizeof ("left")-1)) {
993                 a_style->float_type = FLOAT_LEFT;
994         } else if (!strncmp ("right",
995                              a_value->content.str->stryng->str, 
996                              sizeof ("right")-1)) {
997                 a_style->float_type = FLOAT_RIGHT;
998         } else if (!strncmp ("inherit",
999                              a_value->content.str->stryng->str, 
1000                              sizeof ("inherit")-1)) {
1001                 a_style->float_type = FLOAT_INHERIT;
1002         }
1003         return CR_OK;
1006 static enum CRStatus
1007 set_prop_width (CRStyle * a_style, CRTerm * a_value)
1009         CRNum *width = NULL;
1010         g_return_val_if_fail (a_style 
1011                               && a_value, 
1012                               CR_BAD_PARAM_ERROR);
1014         width = &a_style->num_props[NUM_PROP_WIDTH].sv;
1015         cr_num_set (width, 0.0, NUM_AUTO);
1017         if (a_value->type == TERM_IDENT) {
1018                 if (a_value->content.str 
1019                     && a_value->content.str->stryng
1020                     && a_value->content.str->stryng->str) {
1021                         if (!strncmp ("auto",
1022                                       a_value->content.str->stryng->str,
1023                                       sizeof ("auto")-1)) {
1024                                 cr_num_set (width, 0.0, NUM_AUTO);
1025                         } else if (!strncmp ("inherit",
1026                                              a_value->content.str->stryng->str,
1027                                              sizeof ("inherit")-1)) {
1028                                 cr_num_set (width, 0.0, NUM_INHERIT);
1029                         }
1030                 }
1031         } else if (a_value->type == TERM_NUMBER) {
1032                 if (a_value->content.num) {
1033                         cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
1034                                      a_value->content.num);
1035                 }
1036         }
1037         return CR_OK;
1040 static enum CRStatus 
1041 set_prop_color (CRStyle * a_style, CRTerm * a_value)
1043         enum CRStatus status = CR_OK;
1044         CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
1046         g_return_val_if_fail (a_style 
1047                               && a_value, CR_BAD_PARAM_ERROR);
1049         status = cr_rgb_set_from_term (a_rgb, a_value);
1051         return status;
1054 static enum CRStatus
1055 set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
1057         enum CRStatus status = CR_OK;
1058         CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
1060         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1062         status = cr_rgb_set_from_term (rgb, a_value);
1063         return status;
1066 /**
1067  *Sets border-top-color, border-right-color,
1068  *border-bottom-color or border-left-color properties
1069  *in the style structure. The value is taken from a
1070  *css2 term of type IDENT or RGB.
1071  *@param a_style the style structure to set.
1072  *@param a_value the css2 term to take the color information from.
1073  *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
1074  *@return CR_OK upon successfull completion, an error code otherwise.
1075  */
1076 static enum CRStatus
1077 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
1078                                     enum CRDirection a_dir)
1080         CRRgb *rgb_color = NULL;
1081         enum CRStatus status = CR_OK;
1083         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1085         switch (a_dir) {
1086         case DIR_TOP:
1087                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
1088                 break;
1090         case DIR_RIGHT:
1091                 rgb_color =
1092                         &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
1093                 break;
1095         case DIR_BOTTOM:
1096                 rgb_color =
1097                         &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
1098                 break;
1100         case DIR_LEFT:
1101                 rgb_color =
1102                         &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
1103                 break;
1105         default:
1106                 cr_utils_trace_info ("unknown DIR type");
1107                 return CR_BAD_PARAM_ERROR;
1108         }
1110         status = CR_UNKNOWN_PROP_VAL_ERROR;
1112         if (a_value->type == TERM_IDENT) {
1113                 if (a_value->content.str 
1114                     && a_value->content.str->stryng
1115                     && a_value->content.str->stryng->str) {
1116                         status = cr_rgb_set_from_name
1117                                 (rgb_color, 
1118                                  (guchar *)a_value->content.str->stryng->str);
1120                 }
1121                 if (status != CR_OK) {
1122                         cr_rgb_set_from_name (rgb_color, (guchar *)"black");
1123                 }
1124         } else if (a_value->type == TERM_RGB) {
1125                 if (a_value->content.rgb) {
1126                         status = cr_rgb_set_from_rgb
1127                                 (rgb_color, a_value->content.rgb);
1128                 }
1129         }
1130         return status;
1133 static enum CRStatus
1134 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
1135                               enum CRDirection a_dir)
1137         CRTerm *cur_term = NULL;
1139         enum CRStatus status = CR_OK;
1141         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1143         for (cur_term = a_value; 
1144              cur_term; 
1145              cur_term = cur_term->next) {
1146                 status = set_prop_border_x_width_from_value (a_style,
1147                                                              cur_term, a_dir);
1149                 if (status != CR_OK) {
1150                         status = set_prop_border_x_style_from_value
1151                                 (a_style, cur_term, a_dir);
1152                 }
1153                 if (status != CR_OK) {
1154                         status = set_prop_border_x_color_from_value
1155                                 (a_style, cur_term, a_dir);
1156                 }
1157         }
1158         return CR_OK;
1161 static enum CRStatus
1162 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
1164         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1166         int dir;
1167         for (dir = 0; dir < (int)NB_DIRS; dir++) {
1168                 set_prop_border_x_from_value (a_style, 
1169                                               a_value, 
1170                                               (enum CRDirection)dir);
1171         }
1173         return CR_OK;
1176 static enum CRStatus
1177 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
1179         CRTerm *cur_term = NULL;
1180         enum CRStatus status = CR_OK;
1181         
1182         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1184         cur_term = a_value;
1186         /*filter the eventual non NUMBER terms some user can have written here*/
1187         while (cur_term && cur_term->type != TERM_NUMBER) {
1188                 cur_term = cur_term->next;
1189         }
1190         if (!cur_term)
1191                 return CR_ERROR ;
1193         int dir;
1194         for (dir = 0; dir < (int)NB_DIRS; dir++) {
1195                 set_prop_padding_x_from_value (a_style,
1196                                             cur_term, (enum CRDirection)dir);
1197         }
1198         cur_term = cur_term->next;
1200         /*filter non NUMBER terms that some users can have written here...*/
1201         while (cur_term && cur_term->type != TERM_NUMBER) {
1202                 cur_term = cur_term->next;
1203         }
1204         /*the user can have just written padding: 1px*/
1205         if (!cur_term)
1206                 return CR_OK;
1208         set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
1209         set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1211         while (cur_term && cur_term->type != TERM_NUMBER) {
1212                 cur_term = cur_term->next;
1213         }
1214         if (!cur_term)
1215                 return CR_OK;
1217         set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
1219         while (cur_term && cur_term->type != TERM_NUMBER) {
1220                 cur_term = cur_term->next;
1221         }
1222         if (!cur_term)
1223                 return CR_OK;
1224         status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1225         return status;
1228 static enum CRStatus
1229 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
1231         CRTerm *cur_term = NULL;
1232         enum CRStatus status = CR_OK;
1234         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1236         cur_term = a_value;
1238         while (cur_term && cur_term->type != TERM_NUMBER) {
1239                 cur_term = cur_term->next;
1240         }
1242         if (!cur_term)
1243                 return CR_OK;
1245         int dir;
1246         for (dir = 0; dir < (int)NB_DIRS; dir++) {
1247                 set_prop_margin_x_from_value(a_style,
1248                                         cur_term, (enum CRDirection)dir);
1249         }
1250         cur_term = cur_term->next;
1252         while (cur_term && cur_term->type != TERM_NUMBER) {
1253                 cur_term = cur_term->next;
1254         }
1255         if (!cur_term)
1256                 return CR_OK;
1258         set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
1259         set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1261         while (cur_term && cur_term->type != TERM_NUMBER) {
1262                 cur_term = cur_term->next;
1263         }
1264         if (!cur_term)
1265                 return CR_OK;
1267         set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
1269         while (cur_term && cur_term->type != TERM_NUMBER) {
1270                 cur_term = cur_term->next;
1271         }
1272         if (!cur_term)
1273                 return CR_OK;
1275         status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);        
1277         return status;
1280 static enum CRStatus
1281 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
1283         CRTerm *cur_term = NULL;
1284         CRFontFamily *font_family = NULL,
1285                 *cur_ff = NULL,
1286                 *cur_ff2 = NULL;
1288         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1290         if (a_value->type == TERM_IDENT &&
1291             a_value->content.str &&
1292             a_value->content.str->stryng &&
1293             a_value->content.str->stryng->str &&
1294             !strcmp ("inherit", a_value->content.str->stryng->str))
1295         {
1296                 font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
1297                 goto out;
1298         }
1300         for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
1301                 switch (cur_term->type) {
1302                 case TERM_IDENT:
1303                         {
1304                                 enum CRFontFamilyType font_type;
1306                                 if (cur_term->content.str
1307                                     && cur_term->content.str->stryng
1308                                     && cur_term->content.str->stryng->str
1309                                     && !strcmp 
1310                                     (cur_term->content.str->stryng->str,
1311                                      "sans-serif")) {
1312                                         font_type = FONT_FAMILY_SANS_SERIF;
1313                                 } else if (cur_term->content.str
1314                                            && cur_term->content.str->stryng
1315                                            && cur_term->content.str->stryng->str
1316                                            && !strcmp 
1317                                            (cur_term->content.str->stryng->str, 
1318                                             "serif")) {
1319                                         font_type = FONT_FAMILY_SERIF;
1320                                 } else if (cur_term->content.str
1321                                            && cur_term->content.str->stryng
1322                                            && cur_term->content.str->stryng->str
1323                                            && !strcmp (cur_term->content.str->stryng->str, 
1324                                                        "cursive")) {
1325                                         font_type = FONT_FAMILY_CURSIVE;
1326                                 } else if (cur_term->content.str
1327                                            && cur_term->content.str->stryng
1328                                            && cur_term->content.str->stryng->str
1329                                            && !strcmp (cur_term->content.str->stryng->str,
1330                                                        "fantasy")) {
1331                                         font_type = FONT_FAMILY_FANTASY;
1332                                 } else if (cur_term->content.str
1333                                            && cur_term->content.str->stryng
1334                                            && cur_term->content.str->stryng->str
1335                                            && !strcmp (cur_term->content.str->stryng->str, 
1336                                                        "monospace")) {
1337                                         font_type = FONT_FAMILY_MONOSPACE;
1338                                 } else {
1339                                         /*
1340                                          *unknown property value.
1341                                          *ignore it.
1342                                          */
1343                                         continue;
1344                                 }
1346                                 cur_ff = cr_font_family_new (font_type, NULL);
1347                         }
1348                         break;
1350                 case TERM_STRING:
1351                         {
1352                                 if (cur_term->content.str
1353                                     && cur_term->content.str->stryng
1354                                     && cur_term->content.str->stryng->str) {
1355                                         cur_ff = cr_font_family_new
1356                                                 (FONT_FAMILY_NON_GENERIC,
1357                                                  (guchar *)cur_term->content.str->stryng->str);
1358                                 }
1359                         }
1360                         break;
1362                 default:
1363                         break;
1364                 }
1366                 cur_ff2 = cr_font_family_append (font_family, cur_ff);
1367                 if (cur_ff2) {
1368                         font_family = cur_ff2;
1369                 }
1370         }
1372  out:
1373         if (font_family) {
1374                 if (a_style->font_family) {
1375                         cr_font_family_destroy (a_style->font_family);
1376                         a_style->font_family = NULL ;
1377                 }
1378                 a_style->font_family = font_family;
1379                 font_family = NULL ;
1380         }
1382         return CR_OK;
1385 static enum CRStatus
1386 init_style_font_size_field (CRStyle * a_style)
1388         g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
1390         memset (&a_style->font_size, 0, 
1391                sizeof (CRFontSizeVal)) ;
1392         /*
1393         if (!a_style->font_size) {
1394                 a_style->font_size = cr_font_size_new ();
1395                 if (!a_style->font_size) {
1396                         return CR_INSTANCIATION_FAILED_ERROR;
1397                 }
1398         } else {
1399                 cr_font_size_clear (a_style->font_size);
1400         }
1401         */
1402         return CR_OK;
1405 static enum CRStatus
1406 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
1408         enum CRStatus status = CR_OK;
1410         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1412         switch (a_value->type) {
1413         case TERM_IDENT:
1414                 if (a_value->content.str
1415                     && a_value->content.str->stryng
1416                     && a_value->content.str->stryng->str
1417                     && !strcmp (a_value->content.str->stryng->str,
1418                                 "xx-small")) {
1419                         status = init_style_font_size_field (a_style);
1420                         g_return_val_if_fail (status == CR_OK, status);
1422                         a_style->font_size.sv.type =
1423                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1424                         a_style->font_size.sv.value.predefined =
1425                                 FONT_SIZE_XX_SMALL;
1427                 } else if (a_value->content.str
1428                            && a_value->content.str->stryng
1429                            && a_value->content.str->stryng->str
1430                            && !strcmp (a_value->content.str->stryng->str, 
1431                                        "x-small")) {
1432                         status = init_style_font_size_field (a_style);
1433                         g_return_val_if_fail (status == CR_OK, status);
1435                         a_style->font_size.sv.type =
1436                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1437                         a_style->font_size.sv.value.predefined =
1438                                 FONT_SIZE_X_SMALL;
1439                 } else if (a_value->content.str
1440                            && a_value->content.str->stryng
1441                            && a_value->content.str->stryng->str
1442                            && !strcmp (a_value->content.str->stryng->str, 
1443                                        "small")) {
1444                         status = init_style_font_size_field (a_style);
1445                         g_return_val_if_fail (status == CR_OK, status);
1447                         a_style->font_size.sv.type =
1448                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1449                         a_style->font_size.sv.value.predefined =
1450                                 FONT_SIZE_SMALL;
1451                 } else if (a_value->content.str
1452                            && a_value->content.str->stryng
1453                            && a_value->content.str->stryng->str
1454                            && !strcmp (a_value->content.str->stryng->str, "medium")) {
1455                         status = init_style_font_size_field (a_style);
1456                         g_return_val_if_fail (status == CR_OK, status);
1458                         a_style->font_size.sv.type =
1459                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1460                         a_style->font_size.sv.value.predefined =
1461                                 FONT_SIZE_MEDIUM;
1462                 } else if (a_value->content.str
1463                            && a_value->content.str->stryng
1464                            && a_value->content.str->stryng->str
1465                            && !strcmp (a_value->content.str->stryng->str, 
1466                                        "large")) {
1467                         status = init_style_font_size_field (a_style);
1468                         g_return_val_if_fail (status == CR_OK, status);
1470                         a_style->font_size.sv.type =
1471                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1472                         a_style->font_size.sv.value.predefined =
1473                                 FONT_SIZE_LARGE;
1474                 } else if (a_value->content.str
1475                            && a_value->content.str->stryng
1476                            && a_value->content.str->stryng->str
1477                            && !strcmp (a_value->content.str->stryng->str, 
1478                                        "x-large")) {
1479                         status = init_style_font_size_field (a_style);
1480                         g_return_val_if_fail (status == CR_OK, status);
1482                         a_style->font_size.sv.type =
1483                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1484                         a_style->font_size.sv.value.predefined =
1485                                 FONT_SIZE_X_LARGE;
1486                 } else if (a_value->content.str
1487                            && a_value->content.str->stryng
1488                            && a_value->content.str->stryng->str
1489                            && !strcmp (a_value->content.str->stryng->str, 
1490                                        "xx-large")) {
1491                         status = init_style_font_size_field (a_style);
1492                         g_return_val_if_fail (status == CR_OK, status);
1494                         a_style->font_size.sv.type =
1495                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
1496                         a_style->font_size.sv.value.predefined =
1497                                 FONT_SIZE_XX_LARGE;
1498                 } else if (a_value->content.str
1499                            && a_value->content.str->stryng
1500                            && a_value->content.str->stryng->str
1501                            && !strcmp (a_value->content.str->stryng->str, 
1502                                        "larger")) {
1503                         status = init_style_font_size_field (a_style);
1504                         g_return_val_if_fail (status == CR_OK, status);
1506                         a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1507                         a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
1508                 } else if (a_value->content.str
1509                            && a_value->content.str->stryng
1510                            && a_value->content.str->stryng->str
1511                            && !strcmp (a_value->content.str->stryng->str, 
1512                                        "smaller")) {
1513                         status = init_style_font_size_field (a_style);
1514                         g_return_val_if_fail (status == CR_OK, status);
1516                         a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1517                         a_style->font_size.sv.value.relative =
1518                                 FONT_SIZE_SMALLER;
1519                 } else if (a_value->content.str
1520                            && a_value->content.str->stryng
1521                            && a_value->content.str->stryng->str
1522                            && !strcmp (a_value->content.str->stryng->str, "inherit")) {
1523                         status = init_style_font_size_field (a_style);
1524                         g_return_val_if_fail (status == CR_OK, status);
1525                         a_style->font_size.sv.type = INHERITED_FONT_SIZE;
1527                 } else {
1528                         cr_utils_trace_info ("Unknow value of font-size") ;
1529                         status = init_style_font_size_field (a_style);
1530                         return CR_UNKNOWN_PROP_VAL_ERROR;
1531                 }
1532                 break;
1534         case TERM_NUMBER:
1535                 if (a_value->content.num) {
1536                         status = init_style_font_size_field (a_style);
1537                         g_return_val_if_fail (status == CR_OK, status);
1539                         a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE;
1540                         cr_num_copy (&a_style->font_size.sv.value.absolute,
1541                                      a_value->content.num) ;
1542                 }
1543                 break;
1545         default:
1546                 status = init_style_font_size_field (a_style);
1547                 return CR_UNKNOWN_PROP_VAL_ERROR;
1548         }
1549         return CR_OK;
1552 static enum CRStatus
1553 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
1555         enum CRStatus status = CR_OK;
1557         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1559         switch (a_value->type) {
1560         case TERM_IDENT:
1561                 if (a_value->content.str 
1562                     && a_value->content.str->stryng
1563                     && a_value->content.str->stryng->str) {
1564                         if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1565                                 a_style->font_style = FONT_STYLE_NORMAL;
1566                         } else if (!strcmp
1567                                    (a_value->content.str->stryng->str,
1568                                     "italic")) {
1569                                 a_style->font_style = FONT_STYLE_ITALIC;
1570                         } else if (!strcmp
1571                                    (a_value->content.str->stryng->str,
1572                                     "oblique")) {
1573                                 a_style->font_style = FONT_STYLE_OBLIQUE;
1574                         } else if (!strcmp
1575                                    (a_value->content.str->stryng->str,
1576                                     "inherit")) {
1577                                 a_style->font_style = FONT_STYLE_INHERIT;
1578                         } else {
1579                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1580                         }
1581                 }
1582                 break;
1584         default:
1585                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1586                 break;
1587         }
1589         return status;
1592 static enum CRStatus
1593 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
1595         enum CRStatus status = CR_OK;
1597         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1599         switch (a_value->type) {
1600         case TERM_IDENT:
1601                 if (a_value->content.str 
1602                     && a_value->content.str->stryng
1603                     && a_value->content.str->stryng->str) {
1604                         if (!strcmp (a_value->content.str->stryng->str, 
1605                                      "normal")) {
1606                                 a_style->font_weight = FONT_WEIGHT_NORMAL;
1607                         } else if (!strcmp (a_value->content.str->stryng->str,
1608                                             "bold")) {
1609                                 a_style->font_weight = FONT_WEIGHT_BOLD;
1610                         } else if (!strcmp (a_value->content.str->stryng->str,
1611                                             "bolder")) {
1612                                 a_style->font_weight = FONT_WEIGHT_BOLDER;
1613                         } else if (!strcmp (a_value->content.str->stryng->str,
1614                                             "lighter")) {
1615                                 a_style->font_weight = FONT_WEIGHT_LIGHTER;
1616                         } else if (!strcmp (a_value->content.str->stryng->str,
1617                                             "inherit")) {
1618                                 a_style->font_weight = FONT_WEIGHT_INHERIT;
1620                         } else {
1621                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1622                         }
1624                 }
1625                 break;
1627         case TERM_NUMBER:
1628                 if (a_value->content.num
1629                     && (a_value->content.num->type == NUM_GENERIC
1630                         || a_value->content.num->type == NUM_AUTO)) {
1631                         if (a_value->content.num->val <= 150) {
1632                                 a_style->font_weight = FONT_WEIGHT_100;
1633                         } else if (a_value->content.num->val <= 250) {
1634                                 a_style->font_weight = FONT_WEIGHT_200;
1635                         } else if (a_value->content.num->val <= 350) {
1636                                 a_style->font_weight = FONT_WEIGHT_300;
1637                         } else if (a_value->content.num->val <= 450) {
1638                                 a_style->font_weight = FONT_WEIGHT_400;
1639                         } else if (a_value->content.num->val <= 550) {
1640                                 a_style->font_weight = FONT_WEIGHT_500;
1641                         } else if (a_value->content.num->val <= 650) {
1642                                 a_style->font_weight = FONT_WEIGHT_600;
1643                         } else if (a_value->content.num->val <= 750) {
1644                                 a_style->font_weight = FONT_WEIGHT_700;
1645                         } else if (a_value->content.num->val <= 850) {
1646                                 a_style->font_weight = FONT_WEIGHT_800;
1647                         } else {
1648                                 a_style->font_weight = FONT_WEIGHT_900;
1649                         }
1650                 }
1651                 break;
1653         default:
1654                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1655                 break;
1656         }
1658         return status;
1661 static enum CRStatus
1662 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
1664         enum CRStatus status = CR_OK;
1666         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1668         switch (a_value->type) {
1669         case TERM_IDENT:
1670                 if (a_value->content.str && a_value->content.str->stryng) {
1671                         if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1672                                 a_style->white_space = WHITE_SPACE_NORMAL;
1673                         } else if (!strcmp (a_value->content.str->stryng->str, 
1674                                             "pre")) {
1675                                 a_style->white_space = WHITE_SPACE_PRE;
1676                         } else if (!strcmp (a_value->content.str->stryng->str,
1677                                             "nowrap")) {
1678                                 a_style->white_space = WHITE_SPACE_NOWRAP;
1679                         } else if (!strcmp (a_value->content.str->stryng->str,
1680                                             "inherit")) {
1681                                 a_style->white_space = WHITE_SPACE_INHERIT;
1682                         } else {
1683                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1684                         }
1685                 }
1686                 break;
1687         default:
1688                 status = CR_UNKNOWN_PROP_VAL_ERROR;
1689                 break;
1690         }
1692         return status;
1695 /******************
1696  *Public methods
1697  ******************/
1699 /**
1700  *Default constructor of #CRStyle.
1701  *@param a_set_props_to_initial_values if TRUE, the style properties
1702  *will be set to the default values. Only the style properties of the
1703  *root box should be set to their initial values.
1704  *Otherwise, the style values are set to their default value.
1705  *Read the CSS2 spec, chapters 6.1.1 to 6.2.
1706  */
1707 CRStyle *
1708 cr_style_new (gboolean a_set_props_to_initial_values)
1710         CRStyle *result = (CRStyle *)g_try_malloc (sizeof (CRStyle));
1711         if (!result) {
1712                 cr_utils_trace_info ("Out of memory");
1713                 return NULL;
1714         }
1715         memset (result, 0, sizeof (CRStyle));
1716         gv_prop_hash_ref_count++;
1718         if (a_set_props_to_initial_values == TRUE) {
1719                 cr_style_set_props_to_initial_values (result);
1720         } else {
1721                 cr_style_set_props_to_default_values (result);
1722         }
1724         return result;
1727 /**
1728  *Sets the style properties to their default values according to the css2 spec
1729  * i.e inherit if the property is inherited, its initial value otherwise.
1730  *@param a_this the current instance of #CRStyle.
1731  *@return CR_OK upon successfull completion, an error code otherwise.
1732  */
1733 enum CRStatus 
1734 cr_style_set_props_to_default_values (CRStyle * a_this)
1736         glong i = 0;
1738         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1739         
1740         for (i = 0; i < NB_NUM_PROPS; i++)
1741         {
1742                 switch (i)
1743                 {
1744                 case NUM_PROP_WIDTH:
1745                 case NUM_PROP_TOP:
1746                 case NUM_PROP_RIGHT:
1747                 case NUM_PROP_BOTTOM:
1748                 case NUM_PROP_LEFT:
1749                         cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1750                         break;
1752                 case NUM_PROP_PADDING_TOP:
1753                 case NUM_PROP_PADDING_RIGHT:
1754                 case NUM_PROP_PADDING_BOTTOM:
1755                 case NUM_PROP_PADDING_LEFT:
1756                 case NUM_PROP_BORDER_TOP:
1757                 case NUM_PROP_BORDER_RIGHT:
1758                 case NUM_PROP_BORDER_BOTTOM:
1759                 case NUM_PROP_BORDER_LEFT:
1760                 case NUM_PROP_MARGIN_TOP:
1761                 case NUM_PROP_MARGIN_RIGHT:
1762                 case NUM_PROP_MARGIN_BOTTOM:
1763                 case NUM_PROP_MARGIN_LEFT:
1764                         cr_num_set (&a_this->num_props[i].sv,
1765                                     0, NUM_LENGTH_PX);
1766                         break;
1768                 default:
1769                         cr_utils_trace_info ("Unknown property");
1770                         break;
1771                 }
1772         }
1774         for (i = 0; i < NB_RGB_PROPS; i++) {
1775                 
1776                 switch (i) {
1777                         /*default foreground color is black */
1778                 case RGB_PROP_COLOR:
1779                         /*
1780                          *REVIEW: color is inherited and the default value is
1781                          *ua dependant.
1782                          */
1783                         cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
1784                                                TRUE) ;
1785                         break;
1787                         /*default background color is white */
1788                 case RGB_PROP_BACKGROUND_COLOR:
1789                         /* TODO: the default value should be transparent */
1790                         cr_rgb_set (&a_this->rgb_props[i].sv,
1791                                     255, 255, 255, FALSE);
1792                         cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1793                                                    TRUE) ;
1794                         break;
1796                 default:
1797                         /* 
1798                          *TODO: for BORDER_COLOR the initial value should
1799                          * be the same as COLOR 
1800                          */
1801                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
1802                                     FALSE);
1803                         break;
1804                 }
1805         }
1807         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1808                 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1809         }
1811         a_this->display = DISPLAY_INLINE;
1812         a_this->position = POSITION_STATIC;
1813         a_this->float_type = FLOAT_NONE;
1814         a_this->parent_style = NULL;
1815         a_this->font_style = FONT_STYLE_INHERIT;
1816         a_this->font_variant = FONT_VARIANT_INHERIT;
1817         a_this->font_weight = FONT_WEIGHT_INHERIT;
1818         a_this->font_family = NULL;
1819         
1820         cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
1821         cr_font_size_clear (&a_this->font_size.cv) ;
1822         cr_font_size_clear (&a_this->font_size.av) ;
1824         /* To make the inheritance resolution possible and efficient */
1825         a_this->inherited_props_resolved = FALSE ;
1826         return CR_OK;
1829 /**
1830  *Sets the style properties to their initial value according to the css2 spec.
1831  *This function should be used to initialize the style of the root element
1832  *of an xml tree.
1833  *Some properties are user agent dependant like font-family, and
1834  *are not initialized, read the spec to make you renderer compliant.
1835  *@param a_this the current instance of #CRStyle.
1836  *@return CR_OK upon successfull completion, an error code otherwise.
1837  */
1838 enum CRStatus 
1839 cr_style_set_props_to_initial_values (CRStyle *a_this)
1841         glong i = 0;
1843         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1845         for (i = 0; i < NB_NUM_PROPS; i++) {
1846                 switch (i) {
1847                 case NUM_PROP_WIDTH:
1848                         cr_num_set (&a_this->num_props[i].sv, 800,
1849                                     NUM_LENGTH_PX) ;
1850                         break ;
1851                 case NUM_PROP_TOP:
1852                 case NUM_PROP_RIGHT:
1853                 case NUM_PROP_BOTTOM:
1854                 case NUM_PROP_LEFT:
1855                         cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1856                         break;
1858                 case NUM_PROP_PADDING_TOP:
1859                 case NUM_PROP_PADDING_RIGHT:
1860                 case NUM_PROP_PADDING_BOTTOM:
1861                 case NUM_PROP_PADDING_LEFT:
1862                 case NUM_PROP_BORDER_TOP:
1863                 case NUM_PROP_BORDER_RIGHT:
1864                 case NUM_PROP_BORDER_BOTTOM:
1865                 case NUM_PROP_BORDER_LEFT:
1866                 case NUM_PROP_MARGIN_TOP:
1867                 case NUM_PROP_MARGIN_RIGHT:
1868                 case NUM_PROP_MARGIN_BOTTOM:
1869                 case NUM_PROP_MARGIN_LEFT:
1870                         cr_num_set (&a_this->num_props[i].sv,
1871                                     0, NUM_LENGTH_PX);
1872                         break;
1874                 default:
1875                         cr_utils_trace_info ("Unknown property");
1876                         break;
1877                 }
1878         }
1880         for (i = 0; i < NB_RGB_PROPS; i++) {
1882                 switch (i) {
1883                         /*default foreground color is black */
1884                 case RGB_PROP_COLOR:
1885                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1886                         break;
1888                         /*default background color is white */
1889                 case RGB_PROP_BACKGROUND_COLOR:
1890                         cr_rgb_set (&a_this->rgb_props[i].sv,
1891                                     255, 255, 255, FALSE);
1892                         cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1893                                                    TRUE) ;                        
1894                         break;
1895                 default:
1896                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1897                         break;
1898                 }
1899         }
1901         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1902                 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1903         }
1905         a_this->display = DISPLAY_BLOCK;
1906         a_this->position = POSITION_STATIC;
1907         a_this->float_type = FLOAT_NONE;
1908         a_this->font_style = FONT_STYLE_NORMAL;
1909         a_this->font_variant = FONT_VARIANT_NORMAL;
1910         a_this->font_weight = FONT_WEIGHT_NORMAL;
1911         a_this->font_stretch = FONT_STRETCH_NORMAL;
1912         a_this->white_space = WHITE_SPACE_NORMAL;
1913         cr_font_size_set_predefined_absolute_font_size
1914                 (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
1915         a_this->inherited_props_resolved = FALSE ;
1917         return CR_OK;
1920 /**
1921  *Resolves the inherited properties.
1922  *The function sets the "inherited" properties to either the value of
1923  *their parent properties.
1924  *This function is *NOT* recursive. So the inherited properties of
1925  *the parent style must have been resolved prior to calling this function.
1926  *@param a_this the instance where 
1927  *@return CR_OK if a root node is found and the propagation is successful,
1928  *an error code otherwise
1929  */
1930 enum CRStatus 
1931 cr_style_resolve_inherited_properties (CRStyle *a_this)
1933         enum CRStatus ret = CR_OK;
1934         glong i = 0;
1936         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1937         g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
1939         if (a_this->inherited_props_resolved == TRUE)
1940                 return CR_OK ;
1942         for (i=0 ; i < NB_NUM_PROPS ;i++) {
1943                 if (a_this->num_props[i].sv.type == NUM_INHERIT) {
1944                         cr_num_copy (&a_this->num_props[i].cv,
1945                                      &a_this->parent_style->num_props[i].cv);
1946                 }
1947         }
1948         for (i=0; i < NB_RGB_PROPS; i++) {
1949                 if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
1950                         cr_rgb_copy (
1951                                 &a_this->rgb_props[i].cv,
1952                                 &a_this->parent_style->rgb_props[i].cv);
1953                 }
1954         }
1955         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1956                 if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
1957                         a_this->border_style_props[i] =
1958                           a_this->parent_style->border_style_props[i];
1959                 }
1960         }
1962         if (a_this->display == DISPLAY_INHERIT) {
1963                 a_this->display = a_this->parent_style->display;
1964         }
1965         if (a_this->position == POSITION_INHERIT) {
1966                 a_this->position = a_this->parent_style->position;
1967         }
1968         if (a_this->float_type == FLOAT_INHERIT) {
1969                 a_this->float_type = a_this->parent_style->float_type;
1970         }
1971         if (a_this->font_style == FONT_STYLE_INHERIT) {
1972                 a_this->font_style = a_this->parent_style->font_style;
1973         }
1974         if (a_this->font_variant == FONT_VARIANT_INHERIT) {
1975                 a_this->font_variant = a_this->parent_style->font_variant;
1976         }
1977         if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
1978                 a_this->font_weight = a_this->parent_style->font_weight;
1979         }
1980         if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
1981                 a_this->font_stretch = a_this->parent_style->font_stretch;
1982         }
1983         /*NULL is inherit marker for font_famiy*/
1984         if (a_this->font_family == NULL)  {
1985                 a_this->font_family = a_this->parent_style->font_family;
1986         }
1987         if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
1988                 cr_font_size_copy (&a_this->font_size.cv,
1989                                    &a_this->parent_style->font_size.cv) ;
1990         }
1991         a_this->inherited_props_resolved = TRUE ;
1992         return ret;
1995 /**
1996  *Walks through a css2 property declaration, and populated the
1997  *according field(s) in the #CRStyle structure.
1998  *If the properties or their value(s) are/is not known, 
1999  *sets the corresponding field(s) of #CRStyle to its/their default 
2000  *value(s)
2001  *@param a_this the instance of #CRStyle to set.
2002  *@param a_decl the declaration from which the #CRStyle fields are set.
2003  *@return CR_OK upon successfull completion, an error code otherwise.
2004  */
2005 enum CRStatus
2006 cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl)
2008         CRTerm *value = NULL;
2009         enum CRStatus status = CR_OK;
2011         enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN;
2013         g_return_val_if_fail (a_this && a_decl
2014                               && a_decl
2015                               && a_decl->property
2016                               && a_decl->property->stryng
2017                               && a_decl->property->stryng->str,
2018                               CR_BAD_PARAM_ERROR);
2020         prop_id = cr_style_get_prop_id
2021                 ((guchar *)a_decl->property->stryng->str);
2023         value = a_decl->value;
2024         switch (prop_id) {
2025         case PROP_ID_PADDING_TOP:
2026                 status = set_prop_padding_x_from_value
2027                         (a_this, value, DIR_TOP);
2028                 break;
2030         case PROP_ID_PADDING_RIGHT:
2031                 status = set_prop_padding_x_from_value
2032                         (a_this, value, DIR_RIGHT);
2033                 break;
2034         case PROP_ID_PADDING_BOTTOM:
2035                 status = set_prop_padding_x_from_value
2036                         (a_this, value, DIR_BOTTOM);
2037                 break;
2039         case PROP_ID_PADDING_LEFT:
2040                 status = set_prop_padding_x_from_value
2041                         (a_this, value, DIR_LEFT);
2042                 break;
2044         case PROP_ID_PADDING:
2045                 status = set_prop_padding_from_value (a_this, value) ;
2046                 break;
2048         case PROP_ID_BORDER_TOP_WIDTH:
2049                 status = set_prop_border_x_width_from_value (a_this, value,
2050                                                              DIR_TOP);
2051                 break;
2053         case PROP_ID_BORDER_RIGHT_WIDTH:
2054                 status = set_prop_border_x_width_from_value (a_this, value,
2055                                                              DIR_RIGHT);
2056                 break;
2058         case PROP_ID_BORDER_BOTTOM_WIDTH:
2059                 status = set_prop_border_x_width_from_value (a_this, value,
2060                                                              DIR_BOTTOM);
2061                 break;
2063         case PROP_ID_BORDER_LEFT_WIDTH:
2064                 status = set_prop_border_x_width_from_value (a_this, value,
2065                                                              DIR_LEFT);
2066                 break;
2068         case PROP_ID_BORDER_WIDTH:
2069                 status = set_prop_border_width_from_value (a_this, value) ;
2070                 break ;
2072         case PROP_ID_BORDER_TOP_STYLE:
2073                 status = set_prop_border_x_style_from_value (a_this, value,
2074                                                              DIR_TOP);
2075                 break;
2077         case PROP_ID_BORDER_RIGHT_STYLE:
2078                 status = set_prop_border_x_style_from_value (a_this, value,
2079                                                              DIR_RIGHT);
2080                 break;
2082         case PROP_ID_BORDER_BOTTOM_STYLE:
2083                 status = set_prop_border_x_style_from_value (a_this, value,
2084                                                              DIR_BOTTOM);
2085                 break;
2087         case PROP_ID_BORDER_LEFT_STYLE:
2088                 status = set_prop_border_x_style_from_value (a_this, value,
2089                                                              DIR_LEFT);
2090                 break;
2092         case PROP_ID_BORDER_STYLE:
2093                 status = set_prop_border_style_from_value (a_this, value) ;
2094                 break ;
2096         case PROP_ID_BORDER_TOP_COLOR:
2097                 status = set_prop_border_x_color_from_value (a_this, value,
2098                                                              DIR_TOP);
2099                 break;
2101         case PROP_ID_BORDER_RIGHT_COLOR:
2102                 status = set_prop_border_x_color_from_value (a_this, value,
2103                                                              DIR_RIGHT);
2104                 break;
2106         case PROP_ID_BORDER_BOTTOM_COLOR:
2107                 status = set_prop_border_x_color_from_value (a_this, value,
2108                                                              DIR_BOTTOM);
2109                 break;
2111         case PROP_ID_BORDER_LEFT_COLOR:
2112                 status = set_prop_border_x_color_from_value (a_this, value,
2113                                                              DIR_BOTTOM);
2114                 break;
2116         case PROP_ID_BORDER_TOP:
2117                 status = set_prop_border_x_from_value (a_this, value,
2118                                                        DIR_TOP);
2119                 break;
2121         case PROP_ID_BORDER_RIGHT:
2122                 status = set_prop_border_x_from_value (a_this, value,
2123                                                        DIR_RIGHT);
2124                 break;
2126         case PROP_ID_BORDER_BOTTOM:
2127                 status = set_prop_border_x_from_value (a_this, value,
2128                                                        DIR_BOTTOM);
2129                 break;
2131         case PROP_ID_BORDER_LEFT:
2132                 status = set_prop_border_x_from_value (a_this, value,
2133                                                        DIR_LEFT);
2134                 break;
2136         case PROP_ID_MARGIN_TOP:
2137                 status = set_prop_margin_x_from_value (a_this, value,
2138                                                        DIR_TOP);
2139                 break;
2141         case PROP_ID_BORDER:
2142                 status = set_prop_border_from_value (a_this, value);
2143                 break;
2145         case PROP_ID_MARGIN_RIGHT:
2146                 status = set_prop_margin_x_from_value (a_this, value,
2147                                                        DIR_RIGHT);
2148                 break;
2150         case PROP_ID_MARGIN_BOTTOM:
2151                 status = set_prop_margin_x_from_value (a_this, value,
2152                                                        DIR_BOTTOM);
2153                 break;
2155         case PROP_ID_MARGIN_LEFT:
2156                 status = set_prop_margin_x_from_value (a_this, value,
2157                                                        DIR_LEFT);
2158                 break;
2160         case PROP_ID_MARGIN:
2161                 status = set_prop_margin_from_value (a_this, value);
2162                 break;
2164         case PROP_ID_DISPLAY:
2165                 status = set_prop_display_from_value (a_this, value);
2166                 break;
2168         case PROP_ID_POSITION:
2169                 status = set_prop_position_from_value (a_this, value);
2170                 break;
2172         case PROP_ID_TOP:
2173                 status = set_prop_x_from_value (a_this, value, DIR_TOP);
2174                 break;
2176         case PROP_ID_RIGHT:
2177                 status = set_prop_x_from_value (a_this, value, DIR_RIGHT);
2178                 break;
2180         case PROP_ID_BOTTOM:
2181                 status = set_prop_x_from_value (a_this, value, DIR_BOTTOM);
2182                 break;
2184         case PROP_ID_LEFT:
2185                 status = set_prop_x_from_value (a_this, value, DIR_LEFT);
2186                 break;
2188         case PROP_ID_FLOAT:
2189                 status = set_prop_float (a_this, value);
2190                 break;
2192         case PROP_ID_WIDTH:
2193                 status = set_prop_width (a_this, value);
2194                 break;
2196         case PROP_ID_COLOR:
2197                 status = set_prop_color (a_this, value);
2198                 break;
2200         case PROP_ID_BACKGROUND_COLOR:
2201                 status = set_prop_background_color (a_this, value);
2202                 break;
2204         case PROP_ID_FONT_FAMILY:
2205                 status = set_prop_font_family_from_value (a_this, value);
2206                 break;
2208         case PROP_ID_FONT_SIZE:
2209                 status = set_prop_font_size_from_value (a_this, value);
2210                 break;
2212         case PROP_ID_FONT_STYLE:
2213                 status = set_prop_font_style_from_value (a_this, value);
2214                 break;
2216         case PROP_ID_FONT_WEIGHT:
2217                 status = set_prop_font_weight_from_value (a_this, value);
2218                 break;
2220         case PROP_ID_WHITE_SPACE:
2221                 status = set_prop_white_space_from_value(a_this, value);
2222                 break;
2224         default:
2225                 return CR_UNKNOWN_TYPE_ERROR;
2227         }
2229         return status;
2232 /**
2233  *Increases the reference count
2234  *of the current instance of #CRStyle.
2235  *@param a_this the current instance of #CRStyle.
2236  *@return CR_OK upon successfull completion, an error code
2237  *otherwise.
2238  */
2239 enum CRStatus
2240 cr_style_ref (CRStyle * a_this)
2242         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
2244         a_this->ref_count++;
2245         return CR_OK;
2248 /**
2249  *Decreases the reference count of
2250  *the current instance of #CRStyle.
2251  *If the reference count reaches 0, the
2252  *instance of #CRStyle is destoyed.
2253  *@param a_this the current instance of #CRStyle.
2254  *@return TRUE if the instance has been destroyed, FALSE
2255  *otherwise.
2256  */
2257 gboolean
2258 cr_style_unref (CRStyle * a_this)
2260         g_return_val_if_fail (a_this, FALSE);
2262         if (a_this->ref_count)
2263                 a_this->ref_count--;
2265         if (!a_this->ref_count) {
2266                 cr_style_destroy (a_this);
2267                 return TRUE;
2268         }
2270         return FALSE;
2273 /**
2274  *Duplicates the current instance of #CRStyle .
2275  *The newly created instance of #CRStyle must be
2276  *freed using cr_style_destroy ().
2277  *@param a_this the current instance of #CRStyle.
2278  *@return the newly duplicated instance of #CRStyle.
2279  */
2280 CRStyle *
2281 cr_style_dup (CRStyle * a_this)
2283         CRStyle *result = NULL;
2285         g_return_val_if_fail (a_this, NULL);
2287         result = cr_style_new (FALSE);
2288         if (!result) {
2289                 cr_utils_trace_info ("Out of memory");
2290                 return NULL;
2291         }
2292         cr_style_copy (result, a_this);
2293         return result;
2296 /**
2297  *Copies a style data structure into another.
2298  *TODO: this is actually broken because it's based
2299  *on memcpy although some data stuctures of CRStyle should
2300  *be properly duplicated.
2301  *@param a_dest the destination style datastructure
2302  *@param a_src the source style datastructure.
2303  *@return CR_OK upon succesfull completion, an error code otherwise
2304  */
2305 enum CRStatus
2306 cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
2308         g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
2310         memcpy (a_dest, a_src, sizeof (CRStyle));
2311         return CR_OK;
2314 /**
2315  *dump a CRNumpPropVal in a string.
2316  *@param a_prop_val the numerical property value to dump
2317  *@param a_str the string to dump the numerical propertie into.
2318  *Note that the string value is appended to a_str.
2319  *@param a_nb_indent the number white chars of indentation.
2320  */
2321 enum CRStatus
2322 cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
2323                                  GString * a_str, guint a_nb_indent)
2325         enum CRStatus status = CR_OK;
2326         guchar *tmp_str = NULL;
2327         GString *str = NULL;
2329         g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2331         str = g_string_new (NULL);
2332         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2333         g_string_append (str, "NumPropVal {");
2334         tmp_str = cr_num_to_string (&a_prop_val->sv);
2335         if (!tmp_str) {
2336                 status = CR_ERROR;
2337                 goto cleanup;
2338         }
2339         g_string_append_printf (str, "sv: %s ", tmp_str);
2340         g_free (tmp_str);
2341         tmp_str = NULL;
2342         
2343         tmp_str = cr_num_to_string (&a_prop_val->cv);
2344         if (!tmp_str) {
2345                 status = CR_ERROR;
2346                 goto cleanup;
2347         }
2348         g_string_append_printf (str, "cv: %s ", tmp_str);
2349         g_free (tmp_str);
2350         tmp_str = NULL;
2352         tmp_str = cr_num_to_string (&a_prop_val->av);
2353         if (!tmp_str) {
2354                 status = CR_ERROR;
2355                 goto cleanup;
2356         }
2357         g_string_append_printf (str, "av: %s ", tmp_str);
2358         g_free (tmp_str);
2359         tmp_str = NULL;
2360         g_string_append (str, "}");
2361         g_string_append (a_str, str->str);
2362         status = CR_OK;
2363       cleanup:
2365         if (tmp_str) {
2366                 g_free (tmp_str);
2367                 tmp_str = NULL;
2368         }
2369         if (str) {
2370                 g_string_free (str, TRUE);
2371         }
2372         return status;
2375 enum CRStatus
2376 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
2377                                  GString * a_str, guint a_nb_indent)
2379         enum CRStatus status = CR_OK;
2380         guchar *tmp_str = NULL;
2381         GString *str = NULL;
2383         g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2385         str = g_string_new (NULL);
2387         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2388         g_string_append (str, "RGBPropVal {");
2389         tmp_str = cr_rgb_to_string (&a_prop_val->sv);
2390         if (!tmp_str) {
2391                 status = CR_ERROR;
2392                 goto cleanup;
2393         }
2394         g_string_append_printf (str, "sv: %s ", tmp_str);
2395         g_free (tmp_str);
2396         tmp_str = NULL;
2397         tmp_str = cr_rgb_to_string (&a_prop_val->cv);
2398         if (!tmp_str) {
2399                 status = CR_ERROR;
2400                 goto cleanup;
2401         }
2402         g_string_append_printf (str, "cv: %s ", tmp_str);
2403         g_free (tmp_str);
2404         tmp_str = NULL;
2405         tmp_str = cr_rgb_to_string (&a_prop_val->av);
2406         if (!tmp_str) {
2407                 status = CR_ERROR;
2408                 goto cleanup;
2409         }
2410         g_string_append_printf (str, "av: %s ", tmp_str);
2411         g_free (tmp_str);
2412         tmp_str = NULL;
2414         g_string_append (str, "}");
2415         g_string_append (a_str, str->str);
2416         status = CR_OK;
2417       cleanup:
2419         if (tmp_str) {
2420                 g_free (tmp_str);
2421                 tmp_str = NULL;
2422         }
2423         if (str) {
2424                 g_string_free (str, TRUE);
2425         }
2426         return status;
2429 enum CRStatus
2430 cr_style_border_style_to_string (enum CRBorderStyle a_prop,
2431                                  GString * a_str, guint a_nb_indent)
2433         gchar *str = NULL;
2435         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2437         switch (a_prop) {
2438         case BORDER_STYLE_NONE:
2439                 str = (gchar *) "border-style-none";
2440                 break;
2441         case BORDER_STYLE_HIDDEN:
2442                 str = (gchar *) "border-style-hidden";
2443                 break;
2444         case BORDER_STYLE_DOTTED:
2445                 str = (gchar *) "border-style-dotted";
2446                 break;
2447         case BORDER_STYLE_DASHED:
2448                 str = (gchar *) "border-style-dashed";
2449                 break;
2450         case BORDER_STYLE_SOLID:
2451                 str = (gchar *) "border-style-solid";
2452                 break;
2453         case BORDER_STYLE_DOUBLE:
2454                 str = (gchar *) "border-style-double";
2455                 break;
2456         case BORDER_STYLE_GROOVE:
2457                 str = (gchar *) "border-style-groove";
2458                 break;
2459         case BORDER_STYLE_RIDGE:
2460                 str = (gchar *) "border-style-ridge";
2461                 break;
2462         case BORDER_STYLE_INSET:
2463                 str = (gchar *) "border-style-inset";
2464                 break;
2465         case BORDER_STYLE_OUTSET:
2466                 str = (gchar *) "border-style-outset";
2467                 break;
2468         default:
2469                 str = (gchar *) "unknown border style";
2470                 break;
2471         }
2472         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2473         g_string_append (a_str, str);
2474         return CR_OK;
2477 enum CRStatus
2478 cr_style_display_type_to_string (enum CRDisplayType a_code,
2479                                  GString * a_str, guint a_nb_indent)
2481         gchar *str = NULL;
2483         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2485         switch (a_code) {
2486         case DISPLAY_NONE:
2487                 str = (gchar *) "display-none";
2488                 break;
2489         case DISPLAY_INLINE:
2490                 str = (gchar *) "display-inline";
2491                 break;
2492         case DISPLAY_BLOCK:
2493                 str = (gchar *) "display-block";
2494                 break;
2495         case DISPLAY_LIST_ITEM:
2496                 str = (gchar *) "display-list-item";
2497                 break;
2498         case DISPLAY_RUN_IN:
2499                 str = (gchar *) "display-run-in";
2500                 break;
2501         case DISPLAY_COMPACT:
2502                 str = (gchar *) "display-compact";
2503                 break;
2504         case DISPLAY_MARKER:
2505                 str = (gchar *) "display-marker";
2506                 break;
2507         case DISPLAY_TABLE:
2508                 str = (gchar *) "display-table";
2509                 break;
2510         case DISPLAY_INLINE_TABLE:
2511                 str = (gchar *) "display-inline-table";
2512                 break;
2513         case DISPLAY_TABLE_ROW_GROUP:
2514                 str = (gchar *) "display-table-row-group";
2515                 break;
2516         case DISPLAY_TABLE_HEADER_GROUP:
2517                 str = (gchar *) "display-table-header-group";
2518                 break;
2519         case DISPLAY_TABLE_FOOTER_GROUP:
2520                 str = (gchar *) "display-table-footer-group";
2521                 break;
2522         case DISPLAY_TABLE_ROW:
2523                 str = (gchar *) "display-table-row";
2524                 break;
2525         case DISPLAY_TABLE_COLUMN_GROUP:
2526                 str = (gchar *) "display-table-column-group";
2527                 break;
2528         case DISPLAY_TABLE_COLUMN:
2529                 str = (gchar *) "display-table-column";
2530                 break;
2531         case DISPLAY_TABLE_CELL:
2532                 str = (gchar *) "display-table-cell";
2533                 break;
2534         case DISPLAY_TABLE_CAPTION:
2535                 str = (gchar *) "display-table-caption";
2536                 break;
2537         case DISPLAY_INHERIT:
2538                 str = (gchar *) "display-inherit";
2539                 break;
2540         default:
2541                 str = (gchar *) "unknown display property";
2542                 break;
2543         }
2544         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2545         g_string_append (a_str, str);
2546         return CR_OK;
2550 enum CRStatus
2551 cr_style_position_type_to_string (enum CRPositionType a_code,
2552                                   GString * a_str, guint a_nb_indent)
2554         gchar *str = NULL;
2556         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2558         switch (a_code) {
2559         case POSITION_STATIC:
2560                 str = (gchar *) "position-static";
2561                 break;
2562         case POSITION_RELATIVE:
2563                 str = (gchar *) "position-relative";
2564                 break;
2565         case POSITION_ABSOLUTE:
2566                 str = (gchar *) "position-absolute";
2567                 break;
2568         case POSITION_FIXED:
2569                 str = (gchar *) "position-fixed";
2570                 break;
2571         case POSITION_INHERIT:
2572                 str = (gchar *) "position-inherit";
2573                 break;
2574         default:
2575                 str = (gchar *) "unknown static property";
2576         }
2577         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2578         g_string_append (a_str, str);
2579         return CR_OK;
2582 enum CRStatus
2583 cr_style_float_type_to_string (enum CRFloatType a_code,
2584                                GString * a_str, guint a_nb_indent)
2586         gchar *str = NULL;
2588         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2590         switch (a_code) {
2591         case FLOAT_NONE:
2592                 str = (gchar *) "float-none";
2593                 break;
2594         case FLOAT_LEFT:
2595                 str = (gchar *) "float-left";
2596                 break;
2597         case FLOAT_RIGHT:
2598                 str = (gchar *) "float-right";
2599                 break;
2600         case FLOAT_INHERIT:
2601                 str = (gchar *) "float-inherit";
2602                 break;
2603         default:
2604                 str = (gchar *) "unknown float property value";
2605                 break;
2606         }
2607         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2608         g_string_append (a_str, str);
2609         return CR_OK;
2612 enum CRStatus
2613 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
2614                                      GString * a_str, guint a_nb_indent)
2616         gchar *str = NULL;
2618         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2620         switch (a_code) {
2621         case WHITE_SPACE_NORMAL:
2622                 str = (gchar *) "normal";
2623                 break;
2624         case WHITE_SPACE_PRE:
2625                 str = (gchar *) "pre";
2626                 break;
2627         case WHITE_SPACE_NOWRAP:
2628                 str = (gchar *) "nowrap";
2629                 break;
2630         case WHITE_SPACE_INHERIT:
2631                 str = (gchar *) "inherited";
2632                 break;
2633         default:
2634                 str = (gchar *) "unknow white space property value";
2635                 break;
2636         }
2637         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2638         g_string_append (a_str, str);
2639         return CR_OK;
2641  
2642 /**
2643  *Serializes in instance of #CRStyle into
2644  *a string
2645  *@param a_this the instance of #CRStyle to serialize
2646  *@param a_str the string to serialise the style into.
2647  *if *a_str is NULL, a new GString is instanciated, otherwise
2648  *the style serialisation is appended to the existed *a_str
2649  *@param the number of white space char to use for indentation.
2650  *@return CR_OK upon successful completion, an error code otherwise.
2651  */
2652 enum CRStatus
2653 cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
2655         const gint INTERNAL_INDENT = 2;
2656         gint indent = a_nb_indent + INTERNAL_INDENT;
2657         gchar *tmp_str = NULL;
2658         GString *str = NULL;
2659         gint i = 0;
2661         g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
2663         if (!*a_str) {
2664                 str = g_string_new (NULL);
2665         } else {
2666                 str = *a_str;
2667         }
2668         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2669         g_string_append (str, "style {\n");
2671         /*loop over the num_props and to_string() them */
2672         for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
2673                 /*
2674                  *to_string() the name of the num_prop
2675                  *(using num_prop_code_to_string)
2676                  *before outputing it value
2677                  */
2678                 cr_utils_dump_n_chars2 (' ', str, indent);
2679                 tmp_str = (gchar *) num_prop_code_to_string ((enum CRNumProp)i);
2680                 if (tmp_str) {
2681                         g_string_append_printf (str, "%s: ", tmp_str);
2682                 } else {
2683                         g_string_append (str, "NULL");
2684                 }
2685                 tmp_str = NULL;
2686                 cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
2687                                                  a_nb_indent +
2688                                                  INTERNAL_INDENT);
2689                 g_string_append (str, "\n");
2690         }
2691         /*loop over the rgb_props and to_string() them all */
2692         for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
2693                 tmp_str = (gchar *) rgb_prop_code_to_string ((enum CRRgbProp)i);
2694                 cr_utils_dump_n_chars2 (' ', str, indent);
2695                 if (tmp_str) {
2696                         g_string_append_printf (str, "%s: ", tmp_str);
2697                 } else {
2698                         g_string_append (str, "NULL: ");
2699                 }
2700                 tmp_str = NULL;
2701                 cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
2702                                                  a_nb_indent +
2703                                                  INTERNAL_INDENT);
2704                 g_string_append (str, "\n");
2705         }
2706         /*loop over the border_style_props and to_string() them */
2707         for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
2708                 tmp_str = (gchar *) 
2709                                     border_style_prop_code_to_string ((enum CRBorderStyleProp)i);
2710                 cr_utils_dump_n_chars2 (' ', str, indent);
2711                 if (tmp_str) {
2712                         g_string_append_printf (str, "%s: ", tmp_str);
2713                 } else {
2714                         g_string_append (str, "NULL: ");
2715                 }
2716                 tmp_str = NULL;
2717                 cr_style_border_style_to_string (a_this->
2718                                                  border_style_props[i], str,
2719                                                  0);
2720                 g_string_append (str, "\n");
2721         }
2722         cr_utils_dump_n_chars2 (' ', str, indent);
2723         g_string_append (str, "display: ");
2724         cr_style_display_type_to_string (a_this->display, str, 0);
2725         g_string_append (str, "\n");
2727         cr_utils_dump_n_chars2 (' ', str, indent);
2728         g_string_append (str, "position: ");
2729         cr_style_position_type_to_string (a_this->position, str, 0);
2730         g_string_append (str, "\n");
2732         cr_utils_dump_n_chars2 (' ', str, indent);
2733         g_string_append (str, "float-type: ");
2734         cr_style_float_type_to_string (a_this->float_type, str, 0);
2735         g_string_append (str, "\n");
2737         cr_utils_dump_n_chars2 (' ', str, indent);
2738         g_string_append (str, "white-space: ");
2739         cr_style_white_space_type_to_string (a_this->white_space, str, 0);
2740         g_string_append (str, "\n");
2742         cr_utils_dump_n_chars2 (' ', str, indent);
2743         g_string_append (str, "font-family: ");
2744         tmp_str = (gchar *)cr_font_family_to_string (a_this->font_family, TRUE);
2745         if (tmp_str) {
2746                 g_string_append (str, tmp_str);
2747                 g_free (tmp_str);
2748                 tmp_str = NULL;
2749         } else {
2750                 g_string_append (str, "NULL");
2751         }
2752         g_string_append (str, "\n");
2754         cr_utils_dump_n_chars2 (' ', str, indent);
2755         tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
2756         if (tmp_str) {
2757                 g_string_append_printf (str, "font-size {sv:%s, ",
2758                                         tmp_str) ;
2759         } else {
2760                 g_string_append (str, "font-size {sv:NULL, ");
2761         }
2762         tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
2763         if (tmp_str) {
2764                 g_string_append_printf (str, "cv:%s, ", tmp_str);
2765         } else {
2766                 g_string_append (str, "cv:NULL, ");
2767         }
2768         tmp_str = cr_font_size_to_string (&a_this->font_size.av);
2769         if (tmp_str) {
2770                 g_string_append_printf (str, "av:%s}", tmp_str);
2771         } else {
2772                 g_string_append (str, "av:NULL}");
2773         }
2775         tmp_str = NULL;
2776         g_string_append (str, "\n");
2778         cr_utils_dump_n_chars2 (' ', str, indent);
2779         tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
2780         if (tmp_str) {
2781                 g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
2782         } else {
2783                 g_string_append (str, "font-size-adjust: NULL");
2784         }
2785         tmp_str = NULL;
2786         g_string_append (str, "\n");
2788         cr_utils_dump_n_chars2 (' ', str, indent);
2789         tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
2790         if (tmp_str) {
2791                 g_string_append_printf (str, "font-style: %s", tmp_str);
2792         } else {
2793                 g_string_append (str, "font-style: NULL");
2794         }
2795         tmp_str = NULL;
2796         g_string_append (str, "\n");
2798         cr_utils_dump_n_chars2 (' ', str, indent);
2799         tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
2800         if (tmp_str) {
2801                 g_string_append_printf (str, "font-variant: %s", tmp_str);
2802         } else {
2803                 g_string_append (str, "font-variant: NULL");
2804         }
2805         tmp_str = NULL;
2806         g_string_append (str, "\n");
2808         cr_utils_dump_n_chars2 (' ', str, indent);
2809         tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
2810         if (tmp_str) {
2811                 g_string_append_printf (str, "font-weight: %s", tmp_str);
2812         } else {
2813                 g_string_append (str, "font-weight: NULL");
2814         }
2815         tmp_str = NULL;
2816         g_string_append (str, "\n");
2818         cr_utils_dump_n_chars2 (' ', str, indent);
2819         tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
2820         if (tmp_str) {
2821                 g_string_append_printf (str, "font-stretch: %s", tmp_str);
2822         } else {
2823                 g_string_append (str, "font-stretch: NULL");
2824         }
2825         tmp_str = NULL;
2826         g_string_append (str, "\n");
2829         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2830         g_string_append (str, "}");
2832         return CR_OK;
2835 /**
2836  *Destructor of the #CRStyle class.
2837  *@param a_this the instance to destroy.
2838  */
2839 void
2840 cr_style_destroy (CRStyle * a_this)
2842         g_return_if_fail (a_this);
2844         g_free (a_this);