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)
321 {
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;
340 }
342 static const gchar *
343 rgb_prop_code_to_string (enum CRRgbProp a_code)
344 {
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;
364 }
366 static const gchar *
367 border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
368 {
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;
388 }
390 static enum CRStatus
391 cr_style_init_properties (void)
392 {
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;
413 }
415 static enum CRPropertyID
416 cr_style_get_prop_id (const guchar * a_prop)
417 {
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);
429 }
431 static enum CRStatus
432 set_prop_padding_x_from_value (CRStyle * a_style,
433 CRTerm * a_value, enum CRDirection a_dir)
434 {
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;
498 }
500 static enum CRStatus
501 set_prop_border_x_width_from_value (CRStyle * a_style,
502 CRTerm * a_value,
503 enum CRDirection a_dir)
504 {
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;
566 }
568 static enum CRStatus
569 set_prop_border_width_from_value (CRStyle *a_style,
570 CRTerm *a_value)
571 {
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 ;
608 }
610 static enum CRStatus
611 set_prop_border_x_style_from_value (CRStyle * a_style,
612 CRTerm * a_value, enum CRDirection a_dir)
613 {
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;
693 }
695 static enum CRStatus
696 set_prop_border_style_from_value (CRStyle *a_style,
697 CRTerm *a_value)
698 {
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 }
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 }
715 cur_term = cur_term->next ;
716 if (!cur_term || cur_term->type != TERM_IDENT) {
717 return CR_OK ;
718 }
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) ;
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 ;
739 }
741 static enum CRStatus
742 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
743 enum CRDirection a_dir)
744 {
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;
799 }
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)
808 {
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;
860 }
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)
869 {
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;
912 }
914 static enum CRStatus
915 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
916 enum CRDirection a_dir)
917 {
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;
967 }
969 static enum CRStatus
970 set_prop_float (CRStyle * a_style, CRTerm * a_value)
971 {
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;
1004 }
1006 static enum CRStatus
1007 set_prop_width (CRStyle * a_style, CRTerm * a_value)
1008 {
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;
1038 }
1040 static enum CRStatus
1041 set_prop_color (CRStyle * a_style, CRTerm * a_value)
1042 {
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;
1052 }
1054 static enum CRStatus
1055 set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
1056 {
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;
1064 }
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)
1079 {
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;
1131 }
1133 static enum CRStatus
1134 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
1135 enum CRDirection a_dir)
1136 {
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;
1159 }
1161 static enum CRStatus
1162 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
1163 {
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;
1174 }
1176 static enum CRStatus
1177 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
1178 {
1179 CRTerm *cur_term = NULL;
1180 enum CRStatus status = CR_OK;
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;
1226 }
1228 static enum CRStatus
1229 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
1230 {
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;
1278 }
1280 static enum CRStatus
1281 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
1282 {
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;
1383 }
1385 static enum CRStatus
1386 init_style_font_size_field (CRStyle * a_style)
1387 {
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;
1403 }
1405 static enum CRStatus
1406 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
1407 {
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;
1550 }
1552 static enum CRStatus
1553 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
1554 {
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;
1590 }
1592 static enum CRStatus
1593 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
1594 {
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;
1659 }
1661 static enum CRStatus
1662 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
1663 {
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;
1693 }
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)
1709 {
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;
1725 }
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)
1735 {
1736 glong i = 0;
1738 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
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++) {
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;
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;
1827 }
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)
1840 {
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;
1918 }
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)
1932 {
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;
1993 }
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)
2007 {
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;
2230 }
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)
2241 {
2242 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
2244 a_this->ref_count++;
2245 return CR_OK;
2246 }
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)
2259 {
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;
2271 }
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)
2282 {
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;
2294 }
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)
2307 {
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;
2312 }
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)
2324 {
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;
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;
2373 }
2375 enum CRStatus
2376 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
2377 GString * a_str, guint a_nb_indent)
2378 {
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;
2427 }
2429 enum CRStatus
2430 cr_style_border_style_to_string (enum CRBorderStyle a_prop,
2431 GString * a_str, guint a_nb_indent)
2432 {
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;
2475 }
2477 enum CRStatus
2478 cr_style_display_type_to_string (enum CRDisplayType a_code,
2479 GString * a_str, guint a_nb_indent)
2480 {
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;
2548 }
2550 enum CRStatus
2551 cr_style_position_type_to_string (enum CRPositionType a_code,
2552 GString * a_str, guint a_nb_indent)
2553 {
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;
2580 }
2582 enum CRStatus
2583 cr_style_float_type_to_string (enum CRFloatType a_code,
2584 GString * a_str, guint a_nb_indent)
2585 {
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;
2610 }
2612 enum CRStatus
2613 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
2614 GString * a_str, guint a_nb_indent)
2615 {
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;
2640 }
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)
2654 {
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;
2833 }
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)
2841 {
2842 g_return_if_fail (a_this);
2844 g_free (a_this);
2845 }