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, (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 {(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 {(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 {(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 (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 for (int dir = (int) DIR_TOP ;
580 dir < (int)NB_DIRS ; dir++) {
581 CRDirection direction = (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 for (int dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++)
708 {
709 CRDirection direction = (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 for (int direction = 0; direction < NB_DIRS; direction++) {
1167 set_prop_border_x_from_value (a_style,
1168 a_value,
1169 (CRDirection)direction);
1170 }
1172 return CR_OK;
1173 }
1175 static enum CRStatus
1176 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
1177 {
1178 CRTerm *cur_term = NULL;
1179 enum CRStatus status = CR_OK;
1181 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1183 cur_term = a_value;
1185 /*filter the eventual non NUMBER terms some user can have written here*/
1186 while (cur_term && cur_term->type != TERM_NUMBER) {
1187 cur_term = cur_term->next;
1188 }
1189 if (!cur_term)
1190 return CR_ERROR ;
1192 for (int direction = 0; direction < (int)NB_DIRS; direction++) {
1193 set_prop_padding_x_from_value (a_style,
1194 cur_term, (CRDirection)direction);
1195 }
1196 cur_term = cur_term->next;
1198 /*filter non NUMBER terms that some users can have written here...*/
1199 while (cur_term && cur_term->type != TERM_NUMBER) {
1200 cur_term = cur_term->next;
1201 }
1202 /*the user can have just written padding: 1px*/
1203 if (!cur_term)
1204 return CR_OK;
1206 set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
1207 set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1209 while (cur_term && cur_term->type != TERM_NUMBER) {
1210 cur_term = cur_term->next;
1211 }
1212 if (!cur_term)
1213 return CR_OK;
1215 set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
1217 while (cur_term && cur_term->type != TERM_NUMBER) {
1218 cur_term = cur_term->next;
1219 }
1220 if (!cur_term)
1221 return CR_OK;
1222 status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1223 return status;
1224 }
1226 static enum CRStatus
1227 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
1228 {
1229 CRTerm *cur_term = NULL;
1230 enum CRStatus status = CR_OK;
1232 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1234 cur_term = a_value;
1236 while (cur_term && cur_term->type != TERM_NUMBER) {
1237 cur_term = cur_term->next;
1238 }
1240 if (!cur_term)
1241 return CR_OK;
1243 for (int direction = 0; direction < (int)NB_DIRS; direction++) {
1244 set_prop_margin_x_from_value(a_style,
1245 cur_term, (CRDirection)direction);
1246 }
1247 cur_term = cur_term->next;
1249 while (cur_term && cur_term->type != TERM_NUMBER) {
1250 cur_term = cur_term->next;
1251 }
1252 if (!cur_term)
1253 return CR_OK;
1255 set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
1256 set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1258 while (cur_term && cur_term->type != TERM_NUMBER) {
1259 cur_term = cur_term->next;
1260 }
1261 if (!cur_term)
1262 return CR_OK;
1264 set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
1266 while (cur_term && cur_term->type != TERM_NUMBER) {
1267 cur_term = cur_term->next;
1268 }
1269 if (!cur_term)
1270 return CR_OK;
1272 status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1274 return status;
1275 }
1277 static enum CRStatus
1278 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
1279 {
1280 CRTerm *cur_term = NULL;
1281 CRFontFamily *font_family = NULL,
1282 *cur_ff = NULL,
1283 *cur_ff2 = NULL;
1285 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1287 if (a_value->type == TERM_IDENT &&
1288 a_value->content.str &&
1289 a_value->content.str->stryng &&
1290 a_value->content.str->stryng->str &&
1291 !strcmp ("inherit", a_value->content.str->stryng->str))
1292 {
1293 font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
1294 goto out;
1295 }
1297 for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
1298 switch (cur_term->type) {
1299 case TERM_IDENT:
1300 {
1301 enum CRFontFamilyType font_type;
1303 if (cur_term->content.str
1304 && cur_term->content.str->stryng
1305 && cur_term->content.str->stryng->str
1306 && !strcmp
1307 (cur_term->content.str->stryng->str,
1308 "sans-serif")) {
1309 font_type = FONT_FAMILY_SANS_SERIF;
1310 } else if (cur_term->content.str
1311 && cur_term->content.str->stryng
1312 && cur_term->content.str->stryng->str
1313 && !strcmp
1314 (cur_term->content.str->stryng->str,
1315 "serif")) {
1316 font_type = FONT_FAMILY_SERIF;
1317 } else if (cur_term->content.str
1318 && cur_term->content.str->stryng
1319 && cur_term->content.str->stryng->str
1320 && !strcmp (cur_term->content.str->stryng->str,
1321 "cursive")) {
1322 font_type = FONT_FAMILY_CURSIVE;
1323 } else if (cur_term->content.str
1324 && cur_term->content.str->stryng
1325 && cur_term->content.str->stryng->str
1326 && !strcmp (cur_term->content.str->stryng->str,
1327 "fantasy")) {
1328 font_type = FONT_FAMILY_FANTASY;
1329 } else if (cur_term->content.str
1330 && cur_term->content.str->stryng
1331 && cur_term->content.str->stryng->str
1332 && !strcmp (cur_term->content.str->stryng->str,
1333 "monospace")) {
1334 font_type = FONT_FAMILY_MONOSPACE;
1335 } else {
1336 /*
1337 *unknown property value.
1338 *ignore it.
1339 */
1340 continue;
1341 }
1343 cur_ff = cr_font_family_new (font_type, NULL);
1344 }
1345 break;
1347 case TERM_STRING:
1348 {
1349 if (cur_term->content.str
1350 && cur_term->content.str->stryng
1351 && cur_term->content.str->stryng->str) {
1352 cur_ff = cr_font_family_new
1353 (FONT_FAMILY_NON_GENERIC,
1354 (guchar *)cur_term->content.str->stryng->str);
1355 }
1356 }
1357 break;
1359 default:
1360 break;
1361 }
1363 cur_ff2 = cr_font_family_append (font_family, cur_ff);
1364 if (cur_ff2) {
1365 font_family = cur_ff2;
1366 }
1367 }
1369 out:
1370 if (font_family) {
1371 if (a_style->font_family) {
1372 cr_font_family_destroy (a_style->font_family);
1373 a_style->font_family = NULL ;
1374 }
1375 a_style->font_family = font_family;
1376 font_family = NULL ;
1377 }
1379 return CR_OK;
1380 }
1382 static enum CRStatus
1383 init_style_font_size_field (CRStyle * a_style)
1384 {
1385 g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
1387 memset (&a_style->font_size, 0,
1388 sizeof (CRFontSizeVal)) ;
1389 /*
1390 if (!a_style->font_size) {
1391 a_style->font_size = cr_font_size_new ();
1392 if (!a_style->font_size) {
1393 return CR_INSTANCIATION_FAILED_ERROR;
1394 }
1395 } else {
1396 cr_font_size_clear (a_style->font_size);
1397 }
1398 */
1399 return CR_OK;
1400 }
1402 static enum CRStatus
1403 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
1404 {
1405 enum CRStatus status = CR_OK;
1407 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1409 switch (a_value->type) {
1410 case TERM_IDENT:
1411 if (a_value->content.str
1412 && a_value->content.str->stryng
1413 && a_value->content.str->stryng->str
1414 && !strcmp (a_value->content.str->stryng->str,
1415 "xx-small")) {
1416 status = init_style_font_size_field (a_style);
1417 g_return_val_if_fail (status == CR_OK, status);
1419 a_style->font_size.sv.type =
1420 PREDEFINED_ABSOLUTE_FONT_SIZE;
1421 a_style->font_size.sv.value.predefined =
1422 FONT_SIZE_XX_SMALL;
1424 } else if (a_value->content.str
1425 && a_value->content.str->stryng
1426 && a_value->content.str->stryng->str
1427 && !strcmp (a_value->content.str->stryng->str,
1428 "x-small")) {
1429 status = init_style_font_size_field (a_style);
1430 g_return_val_if_fail (status == CR_OK, status);
1432 a_style->font_size.sv.type =
1433 PREDEFINED_ABSOLUTE_FONT_SIZE;
1434 a_style->font_size.sv.value.predefined =
1435 FONT_SIZE_X_SMALL;
1436 } else if (a_value->content.str
1437 && a_value->content.str->stryng
1438 && a_value->content.str->stryng->str
1439 && !strcmp (a_value->content.str->stryng->str,
1440 "small")) {
1441 status = init_style_font_size_field (a_style);
1442 g_return_val_if_fail (status == CR_OK, status);
1444 a_style->font_size.sv.type =
1445 PREDEFINED_ABSOLUTE_FONT_SIZE;
1446 a_style->font_size.sv.value.predefined =
1447 FONT_SIZE_SMALL;
1448 } else if (a_value->content.str
1449 && a_value->content.str->stryng
1450 && a_value->content.str->stryng->str
1451 && !strcmp (a_value->content.str->stryng->str, "medium")) {
1452 status = init_style_font_size_field (a_style);
1453 g_return_val_if_fail (status == CR_OK, status);
1455 a_style->font_size.sv.type =
1456 PREDEFINED_ABSOLUTE_FONT_SIZE;
1457 a_style->font_size.sv.value.predefined =
1458 FONT_SIZE_MEDIUM;
1459 } else if (a_value->content.str
1460 && a_value->content.str->stryng
1461 && a_value->content.str->stryng->str
1462 && !strcmp (a_value->content.str->stryng->str,
1463 "large")) {
1464 status = init_style_font_size_field (a_style);
1465 g_return_val_if_fail (status == CR_OK, status);
1467 a_style->font_size.sv.type =
1468 PREDEFINED_ABSOLUTE_FONT_SIZE;
1469 a_style->font_size.sv.value.predefined =
1470 FONT_SIZE_LARGE;
1471 } else if (a_value->content.str
1472 && a_value->content.str->stryng
1473 && a_value->content.str->stryng->str
1474 && !strcmp (a_value->content.str->stryng->str,
1475 "x-large")) {
1476 status = init_style_font_size_field (a_style);
1477 g_return_val_if_fail (status == CR_OK, status);
1479 a_style->font_size.sv.type =
1480 PREDEFINED_ABSOLUTE_FONT_SIZE;
1481 a_style->font_size.sv.value.predefined =
1482 FONT_SIZE_X_LARGE;
1483 } else if (a_value->content.str
1484 && a_value->content.str->stryng
1485 && a_value->content.str->stryng->str
1486 && !strcmp (a_value->content.str->stryng->str,
1487 "xx-large")) {
1488 status = init_style_font_size_field (a_style);
1489 g_return_val_if_fail (status == CR_OK, status);
1491 a_style->font_size.sv.type =
1492 PREDEFINED_ABSOLUTE_FONT_SIZE;
1493 a_style->font_size.sv.value.predefined =
1494 FONT_SIZE_XX_LARGE;
1495 } else if (a_value->content.str
1496 && a_value->content.str->stryng
1497 && a_value->content.str->stryng->str
1498 && !strcmp (a_value->content.str->stryng->str,
1499 "larger")) {
1500 status = init_style_font_size_field (a_style);
1501 g_return_val_if_fail (status == CR_OK, status);
1503 a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1504 a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
1505 } else if (a_value->content.str
1506 && a_value->content.str->stryng
1507 && a_value->content.str->stryng->str
1508 && !strcmp (a_value->content.str->stryng->str,
1509 "smaller")) {
1510 status = init_style_font_size_field (a_style);
1511 g_return_val_if_fail (status == CR_OK, status);
1513 a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1514 a_style->font_size.sv.value.relative =
1515 FONT_SIZE_SMALLER;
1516 } else if (a_value->content.str
1517 && a_value->content.str->stryng
1518 && a_value->content.str->stryng->str
1519 && !strcmp (a_value->content.str->stryng->str, "inherit")) {
1520 status = init_style_font_size_field (a_style);
1521 g_return_val_if_fail (status == CR_OK, status);
1522 a_style->font_size.sv.type = INHERITED_FONT_SIZE;
1524 } else {
1525 cr_utils_trace_info ("Unknow value of font-size") ;
1526 status = init_style_font_size_field (a_style);
1527 return CR_UNKNOWN_PROP_VAL_ERROR;
1528 }
1529 break;
1531 case TERM_NUMBER:
1532 if (a_value->content.num) {
1533 status = init_style_font_size_field (a_style);
1534 g_return_val_if_fail (status == CR_OK, status);
1536 a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE;
1537 cr_num_copy (&a_style->font_size.sv.value.absolute,
1538 a_value->content.num) ;
1539 }
1540 break;
1542 default:
1543 status = init_style_font_size_field (a_style);
1544 return CR_UNKNOWN_PROP_VAL_ERROR;
1545 }
1546 return CR_OK;
1547 }
1549 static enum CRStatus
1550 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
1551 {
1552 enum CRStatus status = CR_OK;
1554 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1556 switch (a_value->type) {
1557 case TERM_IDENT:
1558 if (a_value->content.str
1559 && a_value->content.str->stryng
1560 && a_value->content.str->stryng->str) {
1561 if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1562 a_style->font_style = FONT_STYLE_NORMAL;
1563 } else if (!strcmp
1564 (a_value->content.str->stryng->str,
1565 "italic")) {
1566 a_style->font_style = FONT_STYLE_ITALIC;
1567 } else if (!strcmp
1568 (a_value->content.str->stryng->str,
1569 "oblique")) {
1570 a_style->font_style = FONT_STYLE_OBLIQUE;
1571 } else if (!strcmp
1572 (a_value->content.str->stryng->str,
1573 "inherit")) {
1574 a_style->font_style = FONT_STYLE_INHERIT;
1575 } else {
1576 status = CR_UNKNOWN_PROP_VAL_ERROR;
1577 }
1578 }
1579 break;
1581 default:
1582 status = CR_UNKNOWN_PROP_VAL_ERROR;
1583 break;
1584 }
1586 return status;
1587 }
1589 static enum CRStatus
1590 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
1591 {
1592 enum CRStatus status = CR_OK;
1594 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1596 switch (a_value->type) {
1597 case TERM_IDENT:
1598 if (a_value->content.str
1599 && a_value->content.str->stryng
1600 && a_value->content.str->stryng->str) {
1601 if (!strcmp (a_value->content.str->stryng->str,
1602 "normal")) {
1603 a_style->font_weight = FONT_WEIGHT_NORMAL;
1604 } else if (!strcmp (a_value->content.str->stryng->str,
1605 "bold")) {
1606 a_style->font_weight = FONT_WEIGHT_BOLD;
1607 } else if (!strcmp (a_value->content.str->stryng->str,
1608 "bolder")) {
1609 a_style->font_weight = FONT_WEIGHT_BOLDER;
1610 } else if (!strcmp (a_value->content.str->stryng->str,
1611 "lighter")) {
1612 a_style->font_weight = FONT_WEIGHT_LIGHTER;
1613 } else if (!strcmp (a_value->content.str->stryng->str,
1614 "inherit")) {
1615 a_style->font_weight = FONT_WEIGHT_INHERIT;
1617 } else {
1618 status = CR_UNKNOWN_PROP_VAL_ERROR;
1619 }
1621 }
1622 break;
1624 case TERM_NUMBER:
1625 if (a_value->content.num
1626 && (a_value->content.num->type == NUM_GENERIC
1627 || a_value->content.num->type == NUM_AUTO)) {
1628 if (a_value->content.num->val <= 150) {
1629 a_style->font_weight = FONT_WEIGHT_100;
1630 } else if (a_value->content.num->val <= 250) {
1631 a_style->font_weight = FONT_WEIGHT_200;
1632 } else if (a_value->content.num->val <= 350) {
1633 a_style->font_weight = FONT_WEIGHT_300;
1634 } else if (a_value->content.num->val <= 450) {
1635 a_style->font_weight = FONT_WEIGHT_400;
1636 } else if (a_value->content.num->val <= 550) {
1637 a_style->font_weight = FONT_WEIGHT_500;
1638 } else if (a_value->content.num->val <= 650) {
1639 a_style->font_weight = FONT_WEIGHT_600;
1640 } else if (a_value->content.num->val <= 750) {
1641 a_style->font_weight = FONT_WEIGHT_700;
1642 } else if (a_value->content.num->val <= 850) {
1643 a_style->font_weight = FONT_WEIGHT_800;
1644 } else {
1645 a_style->font_weight = FONT_WEIGHT_900;
1646 }
1647 }
1648 break;
1650 default:
1651 status = CR_UNKNOWN_PROP_VAL_ERROR;
1652 break;
1653 }
1655 return status;
1656 }
1658 static enum CRStatus
1659 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
1660 {
1661 enum CRStatus status = CR_OK;
1663 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1665 switch (a_value->type) {
1666 case TERM_IDENT:
1667 if (a_value->content.str && a_value->content.str->stryng) {
1668 if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1669 a_style->white_space = WHITE_SPACE_NORMAL;
1670 } else if (!strcmp (a_value->content.str->stryng->str,
1671 "pre")) {
1672 a_style->white_space = WHITE_SPACE_PRE;
1673 } else if (!strcmp (a_value->content.str->stryng->str,
1674 "nowrap")) {
1675 a_style->white_space = WHITE_SPACE_NOWRAP;
1676 } else if (!strcmp (a_value->content.str->stryng->str,
1677 "inherit")) {
1678 a_style->white_space = WHITE_SPACE_INHERIT;
1679 } else {
1680 status = CR_UNKNOWN_PROP_VAL_ERROR;
1681 }
1682 }
1683 break;
1684 default:
1685 status = CR_UNKNOWN_PROP_VAL_ERROR;
1686 break;
1687 }
1689 return status;
1690 }
1692 /******************
1693 *Public methods
1694 ******************/
1696 /**
1697 *Default constructor of #CRStyle.
1698 *@param a_set_props_to_initial_values if TRUE, the style properties
1699 *will be set to the default values. Only the style properties of the
1700 *root box should be set to their initial values.
1701 *Otherwise, the style values are set to their default value.
1702 *Read the CSS2 spec, chapters 6.1.1 to 6.2.
1703 */
1704 CRStyle *
1705 cr_style_new (gboolean a_set_props_to_initial_values)
1706 {
1707 CRStyle *result = (CRStyle *)g_try_malloc (sizeof (CRStyle));
1708 if (!result) {
1709 cr_utils_trace_info ("Out of memory");
1710 return NULL;
1711 }
1712 memset (result, 0, sizeof (CRStyle));
1713 gv_prop_hash_ref_count++;
1715 if (a_set_props_to_initial_values == TRUE) {
1716 cr_style_set_props_to_initial_values (result);
1717 } else {
1718 cr_style_set_props_to_default_values (result);
1719 }
1721 return result;
1722 }
1724 /**
1725 *Sets the style properties to their default values according to the css2 spec
1726 * i.e inherit if the property is inherited, its initial value otherwise.
1727 *@param a_this the current instance of #CRStyle.
1728 *@return CR_OK upon successfull completion, an error code otherwise.
1729 */
1730 enum CRStatus
1731 cr_style_set_props_to_default_values (CRStyle * a_this)
1732 {
1733 glong i = 0;
1735 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1737 for (i = 0; i < NB_NUM_PROPS; i++)
1738 {
1739 switch (i)
1740 {
1741 case NUM_PROP_WIDTH:
1742 case NUM_PROP_TOP:
1743 case NUM_PROP_RIGHT:
1744 case NUM_PROP_BOTTOM:
1745 case NUM_PROP_LEFT:
1746 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1747 break;
1749 case NUM_PROP_PADDING_TOP:
1750 case NUM_PROP_PADDING_RIGHT:
1751 case NUM_PROP_PADDING_BOTTOM:
1752 case NUM_PROP_PADDING_LEFT:
1753 case NUM_PROP_BORDER_TOP:
1754 case NUM_PROP_BORDER_RIGHT:
1755 case NUM_PROP_BORDER_BOTTOM:
1756 case NUM_PROP_BORDER_LEFT:
1757 case NUM_PROP_MARGIN_TOP:
1758 case NUM_PROP_MARGIN_RIGHT:
1759 case NUM_PROP_MARGIN_BOTTOM:
1760 case NUM_PROP_MARGIN_LEFT:
1761 cr_num_set (&a_this->num_props[i].sv,
1762 0, NUM_LENGTH_PX);
1763 break;
1765 default:
1766 cr_utils_trace_info ("Unknown property");
1767 break;
1768 }
1769 }
1771 for (i = 0; i < NB_RGB_PROPS; i++) {
1773 switch (i) {
1774 /*default foreground color is black */
1775 case RGB_PROP_COLOR:
1776 /*
1777 *REVIEW: color is inherited and the default value is
1778 *ua dependant.
1779 */
1780 cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
1781 TRUE) ;
1782 break;
1784 /*default background color is white */
1785 case RGB_PROP_BACKGROUND_COLOR:
1786 /* TODO: the default value should be transparent */
1787 cr_rgb_set (&a_this->rgb_props[i].sv,
1788 255, 255, 255, FALSE);
1789 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1790 TRUE) ;
1791 break;
1793 default:
1794 /*
1795 *TODO: for BORDER_COLOR the initial value should
1796 * be the same as COLOR
1797 */
1798 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
1799 FALSE);
1800 break;
1801 }
1802 }
1804 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1805 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1806 }
1808 a_this->display = DISPLAY_INLINE;
1809 a_this->position = POSITION_STATIC;
1810 a_this->float_type = FLOAT_NONE;
1811 a_this->parent_style = NULL;
1812 a_this->font_style = FONT_STYLE_INHERIT;
1813 a_this->font_variant = FONT_VARIANT_INHERIT;
1814 a_this->font_weight = FONT_WEIGHT_INHERIT;
1815 a_this->font_family = NULL;
1817 cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
1818 cr_font_size_clear (&a_this->font_size.cv) ;
1819 cr_font_size_clear (&a_this->font_size.av) ;
1821 /* To make the inheritance resolution possible and efficient */
1822 a_this->inherited_props_resolved = FALSE ;
1823 return CR_OK;
1824 }
1826 /**
1827 *Sets the style properties to their initial value according to the css2 spec.
1828 *This function should be used to initialize the style of the root element
1829 *of an xml tree.
1830 *Some properties are user agent dependant like font-family, and
1831 *are not initialized, read the spec to make you renderer compliant.
1832 *@param a_this the current instance of #CRStyle.
1833 *@return CR_OK upon successfull completion, an error code otherwise.
1834 */
1835 enum CRStatus
1836 cr_style_set_props_to_initial_values (CRStyle *a_this)
1837 {
1838 glong i = 0;
1840 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1842 for (i = 0; i < NB_NUM_PROPS; i++) {
1843 switch (i) {
1844 case NUM_PROP_WIDTH:
1845 cr_num_set (&a_this->num_props[i].sv, 800,
1846 NUM_LENGTH_PX) ;
1847 break ;
1848 case NUM_PROP_TOP:
1849 case NUM_PROP_RIGHT:
1850 case NUM_PROP_BOTTOM:
1851 case NUM_PROP_LEFT:
1852 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1853 break;
1855 case NUM_PROP_PADDING_TOP:
1856 case NUM_PROP_PADDING_RIGHT:
1857 case NUM_PROP_PADDING_BOTTOM:
1858 case NUM_PROP_PADDING_LEFT:
1859 case NUM_PROP_BORDER_TOP:
1860 case NUM_PROP_BORDER_RIGHT:
1861 case NUM_PROP_BORDER_BOTTOM:
1862 case NUM_PROP_BORDER_LEFT:
1863 case NUM_PROP_MARGIN_TOP:
1864 case NUM_PROP_MARGIN_RIGHT:
1865 case NUM_PROP_MARGIN_BOTTOM:
1866 case NUM_PROP_MARGIN_LEFT:
1867 cr_num_set (&a_this->num_props[i].sv,
1868 0, NUM_LENGTH_PX);
1869 break;
1871 default:
1872 cr_utils_trace_info ("Unknown property");
1873 break;
1874 }
1875 }
1877 for (i = 0; i < NB_RGB_PROPS; i++) {
1879 switch (i) {
1880 /*default foreground color is black */
1881 case RGB_PROP_COLOR:
1882 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1883 break;
1885 /*default background color is white */
1886 case RGB_PROP_BACKGROUND_COLOR:
1887 cr_rgb_set (&a_this->rgb_props[i].sv,
1888 255, 255, 255, FALSE);
1889 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1890 TRUE) ;
1891 break;
1892 default:
1893 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1894 break;
1895 }
1896 }
1898 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1899 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1900 }
1902 a_this->display = DISPLAY_BLOCK;
1903 a_this->position = POSITION_STATIC;
1904 a_this->float_type = FLOAT_NONE;
1905 a_this->font_style = FONT_STYLE_NORMAL;
1906 a_this->font_variant = FONT_VARIANT_NORMAL;
1907 a_this->font_weight = FONT_WEIGHT_NORMAL;
1908 a_this->font_stretch = FONT_STRETCH_NORMAL;
1909 a_this->white_space = WHITE_SPACE_NORMAL;
1910 cr_font_size_set_predefined_absolute_font_size
1911 (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
1912 a_this->inherited_props_resolved = FALSE ;
1914 return CR_OK;
1915 }
1917 /**
1918 *Resolves the inherited properties.
1919 *The function sets the "inherited" properties to either the value of
1920 *their parent properties.
1921 *This function is *NOT* recursive. So the inherited properties of
1922 *the parent style must have been resolved prior to calling this function.
1923 *@param a_this the instance where
1924 *@return CR_OK if a root node is found and the propagation is successful,
1925 *an error code otherwise
1926 */
1927 enum CRStatus
1928 cr_style_resolve_inherited_properties (CRStyle *a_this)
1929 {
1930 enum CRStatus ret = CR_OK;
1931 glong i = 0;
1933 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1934 g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
1936 if (a_this->inherited_props_resolved == TRUE)
1937 return CR_OK ;
1939 for (i=0 ; i < NB_NUM_PROPS ;i++) {
1940 if (a_this->num_props[i].sv.type == NUM_INHERIT) {
1941 cr_num_copy (&a_this->num_props[i].cv,
1942 &a_this->parent_style->num_props[i].cv);
1943 }
1944 }
1945 for (i=0; i < NB_RGB_PROPS; i++) {
1946 if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
1947 cr_rgb_copy (
1948 &a_this->rgb_props[i].cv,
1949 &a_this->parent_style->rgb_props[i].cv);
1950 }
1951 }
1952 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1953 if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
1954 a_this->border_style_props[i] =
1955 a_this->parent_style->border_style_props[i];
1956 }
1957 }
1959 if (a_this->display == DISPLAY_INHERIT) {
1960 a_this->display = a_this->parent_style->display;
1961 }
1962 if (a_this->position == POSITION_INHERIT) {
1963 a_this->position = a_this->parent_style->position;
1964 }
1965 if (a_this->float_type == FLOAT_INHERIT) {
1966 a_this->float_type = a_this->parent_style->float_type;
1967 }
1968 if (a_this->font_style == FONT_STYLE_INHERIT) {
1969 a_this->font_style = a_this->parent_style->font_style;
1970 }
1971 if (a_this->font_variant == FONT_VARIANT_INHERIT) {
1972 a_this->font_variant = a_this->parent_style->font_variant;
1973 }
1974 if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
1975 a_this->font_weight = a_this->parent_style->font_weight;
1976 }
1977 if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
1978 a_this->font_stretch = a_this->parent_style->font_stretch;
1979 }
1980 /*NULL is inherit marker for font_famiy*/
1981 if (a_this->font_family == NULL) {
1982 a_this->font_family = a_this->parent_style->font_family;
1983 }
1984 if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
1985 cr_font_size_copy (&a_this->font_size.cv,
1986 &a_this->parent_style->font_size.cv) ;
1987 }
1988 a_this->inherited_props_resolved = TRUE ;
1989 return ret;
1990 }
1992 /**
1993 *Walks through a css2 property declaration, and populated the
1994 *according field(s) in the #CRStyle structure.
1995 *If the properties or their value(s) are/is not known,
1996 *sets the corresponding field(s) of #CRStyle to its/their default
1997 *value(s)
1998 *@param a_this the instance of #CRStyle to set.
1999 *@param a_decl the declaration from which the #CRStyle fields are set.
2000 *@return CR_OK upon successfull completion, an error code otherwise.
2001 */
2002 enum CRStatus
2003 cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl)
2004 {
2005 CRTerm *value = NULL;
2006 enum CRStatus status = CR_OK;
2008 enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN;
2010 g_return_val_if_fail (a_this && a_decl
2011 && a_decl
2012 && a_decl->property
2013 && a_decl->property->stryng
2014 && a_decl->property->stryng->str,
2015 CR_BAD_PARAM_ERROR);
2017 prop_id = cr_style_get_prop_id
2018 ((guchar *)a_decl->property->stryng->str);
2020 value = a_decl->value;
2021 switch (prop_id) {
2022 case PROP_ID_PADDING_TOP:
2023 status = set_prop_padding_x_from_value
2024 (a_this, value, DIR_TOP);
2025 break;
2027 case PROP_ID_PADDING_RIGHT:
2028 status = set_prop_padding_x_from_value
2029 (a_this, value, DIR_RIGHT);
2030 break;
2031 case PROP_ID_PADDING_BOTTOM:
2032 status = set_prop_padding_x_from_value
2033 (a_this, value, DIR_BOTTOM);
2034 break;
2036 case PROP_ID_PADDING_LEFT:
2037 status = set_prop_padding_x_from_value
2038 (a_this, value, DIR_LEFT);
2039 break;
2041 case PROP_ID_PADDING:
2042 status = set_prop_padding_from_value (a_this, value) ;
2043 break;
2045 case PROP_ID_BORDER_TOP_WIDTH:
2046 status = set_prop_border_x_width_from_value (a_this, value,
2047 DIR_TOP);
2048 break;
2050 case PROP_ID_BORDER_RIGHT_WIDTH:
2051 status = set_prop_border_x_width_from_value (a_this, value,
2052 DIR_RIGHT);
2053 break;
2055 case PROP_ID_BORDER_BOTTOM_WIDTH:
2056 status = set_prop_border_x_width_from_value (a_this, value,
2057 DIR_BOTTOM);
2058 break;
2060 case PROP_ID_BORDER_LEFT_WIDTH:
2061 status = set_prop_border_x_width_from_value (a_this, value,
2062 DIR_LEFT);
2063 break;
2065 case PROP_ID_BORDER_WIDTH:
2066 status = set_prop_border_width_from_value (a_this, value) ;
2067 break ;
2069 case PROP_ID_BORDER_TOP_STYLE:
2070 status = set_prop_border_x_style_from_value (a_this, value,
2071 DIR_TOP);
2072 break;
2074 case PROP_ID_BORDER_RIGHT_STYLE:
2075 status = set_prop_border_x_style_from_value (a_this, value,
2076 DIR_RIGHT);
2077 break;
2079 case PROP_ID_BORDER_BOTTOM_STYLE:
2080 status = set_prop_border_x_style_from_value (a_this, value,
2081 DIR_BOTTOM);
2082 break;
2084 case PROP_ID_BORDER_LEFT_STYLE:
2085 status = set_prop_border_x_style_from_value (a_this, value,
2086 DIR_LEFT);
2087 break;
2089 case PROP_ID_BORDER_STYLE:
2090 status = set_prop_border_style_from_value (a_this, value) ;
2091 break ;
2093 case PROP_ID_BORDER_TOP_COLOR:
2094 status = set_prop_border_x_color_from_value (a_this, value,
2095 DIR_TOP);
2096 break;
2098 case PROP_ID_BORDER_RIGHT_COLOR:
2099 status = set_prop_border_x_color_from_value (a_this, value,
2100 DIR_RIGHT);
2101 break;
2103 case PROP_ID_BORDER_BOTTOM_COLOR:
2104 status = set_prop_border_x_color_from_value (a_this, value,
2105 DIR_BOTTOM);
2106 break;
2108 case PROP_ID_BORDER_LEFT_COLOR:
2109 status = set_prop_border_x_color_from_value (a_this, value,
2110 DIR_BOTTOM);
2111 break;
2113 case PROP_ID_BORDER_TOP:
2114 status = set_prop_border_x_from_value (a_this, value,
2115 DIR_TOP);
2116 break;
2118 case PROP_ID_BORDER_RIGHT:
2119 status = set_prop_border_x_from_value (a_this, value,
2120 DIR_RIGHT);
2121 break;
2123 case PROP_ID_BORDER_BOTTOM:
2124 status = set_prop_border_x_from_value (a_this, value,
2125 DIR_BOTTOM);
2126 break;
2128 case PROP_ID_BORDER_LEFT:
2129 status = set_prop_border_x_from_value (a_this, value,
2130 DIR_LEFT);
2131 break;
2133 case PROP_ID_MARGIN_TOP:
2134 status = set_prop_margin_x_from_value (a_this, value,
2135 DIR_TOP);
2136 break;
2138 case PROP_ID_BORDER:
2139 status = set_prop_border_from_value (a_this, value);
2140 break;
2142 case PROP_ID_MARGIN_RIGHT:
2143 status = set_prop_margin_x_from_value (a_this, value,
2144 DIR_RIGHT);
2145 break;
2147 case PROP_ID_MARGIN_BOTTOM:
2148 status = set_prop_margin_x_from_value (a_this, value,
2149 DIR_BOTTOM);
2150 break;
2152 case PROP_ID_MARGIN_LEFT:
2153 status = set_prop_margin_x_from_value (a_this, value,
2154 DIR_LEFT);
2155 break;
2157 case PROP_ID_MARGIN:
2158 status = set_prop_margin_from_value (a_this, value);
2159 break;
2161 case PROP_ID_DISPLAY:
2162 status = set_prop_display_from_value (a_this, value);
2163 break;
2165 case PROP_ID_POSITION:
2166 status = set_prop_position_from_value (a_this, value);
2167 break;
2169 case PROP_ID_TOP:
2170 status = set_prop_x_from_value (a_this, value, DIR_TOP);
2171 break;
2173 case PROP_ID_RIGHT:
2174 status = set_prop_x_from_value (a_this, value, DIR_RIGHT);
2175 break;
2177 case PROP_ID_BOTTOM:
2178 status = set_prop_x_from_value (a_this, value, DIR_BOTTOM);
2179 break;
2181 case PROP_ID_LEFT:
2182 status = set_prop_x_from_value (a_this, value, DIR_LEFT);
2183 break;
2185 case PROP_ID_FLOAT:
2186 status = set_prop_float (a_this, value);
2187 break;
2189 case PROP_ID_WIDTH:
2190 status = set_prop_width (a_this, value);
2191 break;
2193 case PROP_ID_COLOR:
2194 status = set_prop_color (a_this, value);
2195 break;
2197 case PROP_ID_BACKGROUND_COLOR:
2198 status = set_prop_background_color (a_this, value);
2199 break;
2201 case PROP_ID_FONT_FAMILY:
2202 status = set_prop_font_family_from_value (a_this, value);
2203 break;
2205 case PROP_ID_FONT_SIZE:
2206 status = set_prop_font_size_from_value (a_this, value);
2207 break;
2209 case PROP_ID_FONT_STYLE:
2210 status = set_prop_font_style_from_value (a_this, value);
2211 break;
2213 case PROP_ID_FONT_WEIGHT:
2214 status = set_prop_font_weight_from_value (a_this, value);
2215 break;
2217 case PROP_ID_WHITE_SPACE:
2218 status = set_prop_white_space_from_value(a_this, value);
2219 break;
2221 default:
2222 return CR_UNKNOWN_TYPE_ERROR;
2224 }
2226 return status;
2227 }
2229 /**
2230 *Increases the reference count
2231 *of the current instance of #CRStyle.
2232 *@param a_this the current instance of #CRStyle.
2233 *@return CR_OK upon successfull completion, an error code
2234 *otherwise.
2235 */
2236 enum CRStatus
2237 cr_style_ref (CRStyle * a_this)
2238 {
2239 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
2241 a_this->ref_count++;
2242 return CR_OK;
2243 }
2245 /**
2246 *Decreases the reference count of
2247 *the current instance of #CRStyle.
2248 *If the reference count reaches 0, the
2249 *instance of #CRStyle is destoyed.
2250 *@param a_this the current instance of #CRStyle.
2251 *@return TRUE if the instance has been destroyed, FALSE
2252 *otherwise.
2253 */
2254 gboolean
2255 cr_style_unref (CRStyle * a_this)
2256 {
2257 g_return_val_if_fail (a_this, FALSE);
2259 if (a_this->ref_count)
2260 a_this->ref_count--;
2262 if (!a_this->ref_count) {
2263 cr_style_destroy (a_this);
2264 return TRUE;
2265 }
2267 return FALSE;
2268 }
2270 /**
2271 *Duplicates the current instance of #CRStyle .
2272 *The newly created instance of #CRStyle must be
2273 *freed using cr_style_destroy ().
2274 *@param a_this the current instance of #CRStyle.
2275 *@return the newly duplicated instance of #CRStyle.
2276 */
2277 CRStyle *
2278 cr_style_dup (CRStyle * a_this)
2279 {
2280 CRStyle *result = NULL;
2282 g_return_val_if_fail (a_this, NULL);
2284 result = cr_style_new (FALSE);
2285 if (!result) {
2286 cr_utils_trace_info ("Out of memory");
2287 return NULL;
2288 }
2289 cr_style_copy (result, a_this);
2290 return result;
2291 }
2293 /**
2294 *Copies a style data structure into another.
2295 *TODO: this is actually broken because it's based
2296 *on memcpy although some data stuctures of CRStyle should
2297 *be properly duplicated.
2298 *@param a_dest the destination style datastructure
2299 *@param a_src the source style datastructure.
2300 *@return CR_OK upon succesfull completion, an error code otherwise
2301 */
2302 enum CRStatus
2303 cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
2304 {
2305 g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
2307 memcpy (a_dest, a_src, sizeof (CRStyle));
2308 return CR_OK;
2309 }
2311 /**
2312 *dump a CRNumpPropVal in a string.
2313 *@param a_prop_val the numerical property value to dump
2314 *@param a_str the string to dump the numerical propertie into.
2315 *Note that the string value is appended to a_str.
2316 *@param a_nb_indent the number white chars of indentation.
2317 */
2318 enum CRStatus
2319 cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
2320 GString * a_str, guint a_nb_indent)
2321 {
2322 enum CRStatus status = CR_OK;
2323 guchar *tmp_str = NULL;
2324 GString *str = NULL;
2326 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2328 str = g_string_new (NULL);
2329 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2330 g_string_append (str, "NumPropVal {");
2331 tmp_str = cr_num_to_string (&a_prop_val->sv);
2332 if (!tmp_str) {
2333 status = CR_ERROR;
2334 goto cleanup;
2335 }
2336 g_string_append_printf (str, "sv: %s ", tmp_str);
2337 g_free (tmp_str);
2338 tmp_str = NULL;
2340 tmp_str = cr_num_to_string (&a_prop_val->cv);
2341 if (!tmp_str) {
2342 status = CR_ERROR;
2343 goto cleanup;
2344 }
2345 g_string_append_printf (str, "cv: %s ", tmp_str);
2346 g_free (tmp_str);
2347 tmp_str = NULL;
2349 tmp_str = cr_num_to_string (&a_prop_val->av);
2350 if (!tmp_str) {
2351 status = CR_ERROR;
2352 goto cleanup;
2353 }
2354 g_string_append_printf (str, "av: %s ", tmp_str);
2355 g_free (tmp_str);
2356 tmp_str = NULL;
2357 g_string_append (str, "}");
2358 g_string_append (a_str, str->str);
2359 status = CR_OK;
2360 cleanup:
2362 if (tmp_str) {
2363 g_free (tmp_str);
2364 tmp_str = NULL;
2365 }
2366 if (str) {
2367 g_string_free (str, TRUE);
2368 }
2369 return status;
2370 }
2372 enum CRStatus
2373 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
2374 GString * a_str, guint a_nb_indent)
2375 {
2376 enum CRStatus status = CR_OK;
2377 guchar *tmp_str = NULL;
2378 GString *str = NULL;
2380 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2382 str = g_string_new (NULL);
2384 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2385 g_string_append (str, "RGBPropVal {");
2386 tmp_str = cr_rgb_to_string (&a_prop_val->sv);
2387 if (!tmp_str) {
2388 status = CR_ERROR;
2389 goto cleanup;
2390 }
2391 g_string_append_printf (str, "sv: %s ", tmp_str);
2392 g_free (tmp_str);
2393 tmp_str = NULL;
2394 tmp_str = cr_rgb_to_string (&a_prop_val->cv);
2395 if (!tmp_str) {
2396 status = CR_ERROR;
2397 goto cleanup;
2398 }
2399 g_string_append_printf (str, "cv: %s ", tmp_str);
2400 g_free (tmp_str);
2401 tmp_str = NULL;
2402 tmp_str = cr_rgb_to_string (&a_prop_val->av);
2403 if (!tmp_str) {
2404 status = CR_ERROR;
2405 goto cleanup;
2406 }
2407 g_string_append_printf (str, "av: %s ", tmp_str);
2408 g_free (tmp_str);
2409 tmp_str = NULL;
2411 g_string_append (str, "}");
2412 g_string_append (a_str, str->str);
2413 status = CR_OK;
2414 cleanup:
2416 if (tmp_str) {
2417 g_free (tmp_str);
2418 tmp_str = NULL;
2419 }
2420 if (str) {
2421 g_string_free (str, TRUE);
2422 }
2423 return status;
2424 }
2426 enum CRStatus
2427 cr_style_border_style_to_string (enum CRBorderStyle a_prop,
2428 GString * a_str, guint a_nb_indent)
2429 {
2430 gchar *str = NULL;
2432 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2434 switch (a_prop) {
2435 case BORDER_STYLE_NONE:
2436 str = (gchar *) "border-style-none";
2437 break;
2438 case BORDER_STYLE_HIDDEN:
2439 str = (gchar *) "border-style-hidden";
2440 break;
2441 case BORDER_STYLE_DOTTED:
2442 str = (gchar *) "border-style-dotted";
2443 break;
2444 case BORDER_STYLE_DASHED:
2445 str = (gchar *) "border-style-dashed";
2446 break;
2447 case BORDER_STYLE_SOLID:
2448 str = (gchar *) "border-style-solid";
2449 break;
2450 case BORDER_STYLE_DOUBLE:
2451 str = (gchar *) "border-style-double";
2452 break;
2453 case BORDER_STYLE_GROOVE:
2454 str = (gchar *) "border-style-groove";
2455 break;
2456 case BORDER_STYLE_RIDGE:
2457 str = (gchar *) "border-style-ridge";
2458 break;
2459 case BORDER_STYLE_INSET:
2460 str = (gchar *) "border-style-inset";
2461 break;
2462 case BORDER_STYLE_OUTSET:
2463 str = (gchar *) "border-style-outset";
2464 break;
2465 default:
2466 str = (gchar *) "unknown border style";
2467 break;
2468 }
2469 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2470 g_string_append (a_str, str);
2471 return CR_OK;
2472 }
2474 enum CRStatus
2475 cr_style_display_type_to_string (enum CRDisplayType a_code,
2476 GString * a_str, guint a_nb_indent)
2477 {
2478 gchar *str = NULL;
2480 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2482 switch (a_code) {
2483 case DISPLAY_NONE:
2484 str = (gchar *) "display-none";
2485 break;
2486 case DISPLAY_INLINE:
2487 str = (gchar *) "display-inline";
2488 break;
2489 case DISPLAY_BLOCK:
2490 str = (gchar *) "display-block";
2491 break;
2492 case DISPLAY_LIST_ITEM:
2493 str = (gchar *) "display-list-item";
2494 break;
2495 case DISPLAY_RUN_IN:
2496 str = (gchar *) "display-run-in";
2497 break;
2498 case DISPLAY_COMPACT:
2499 str = (gchar *) "display-compact";
2500 break;
2501 case DISPLAY_MARKER:
2502 str = (gchar *) "display-marker";
2503 break;
2504 case DISPLAY_TABLE:
2505 str = (gchar *) "display-table";
2506 break;
2507 case DISPLAY_INLINE_TABLE:
2508 str = (gchar *) "display-inline-table";
2509 break;
2510 case DISPLAY_TABLE_ROW_GROUP:
2511 str = (gchar *) "display-table-row-group";
2512 break;
2513 case DISPLAY_TABLE_HEADER_GROUP:
2514 str = (gchar *) "display-table-header-group";
2515 break;
2516 case DISPLAY_TABLE_FOOTER_GROUP:
2517 str = (gchar *) "display-table-footer-group";
2518 break;
2519 case DISPLAY_TABLE_ROW:
2520 str = (gchar *) "display-table-row";
2521 break;
2522 case DISPLAY_TABLE_COLUMN_GROUP:
2523 str = (gchar *) "display-table-column-group";
2524 break;
2525 case DISPLAY_TABLE_COLUMN:
2526 str = (gchar *) "display-table-column";
2527 break;
2528 case DISPLAY_TABLE_CELL:
2529 str = (gchar *) "display-table-cell";
2530 break;
2531 case DISPLAY_TABLE_CAPTION:
2532 str = (gchar *) "display-table-caption";
2533 break;
2534 case DISPLAY_INHERIT:
2535 str = (gchar *) "display-inherit";
2536 break;
2537 default:
2538 str = (gchar *) "unknown display property";
2539 break;
2540 }
2541 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2542 g_string_append (a_str, str);
2543 return CR_OK;
2545 }
2547 enum CRStatus
2548 cr_style_position_type_to_string (enum CRPositionType a_code,
2549 GString * a_str, guint a_nb_indent)
2550 {
2551 gchar *str = NULL;
2553 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2555 switch (a_code) {
2556 case POSITION_STATIC:
2557 str = (gchar *) "position-static";
2558 break;
2559 case POSITION_RELATIVE:
2560 str = (gchar *) "position-relative";
2561 break;
2562 case POSITION_ABSOLUTE:
2563 str = (gchar *) "position-absolute";
2564 break;
2565 case POSITION_FIXED:
2566 str = (gchar *) "position-fixed";
2567 break;
2568 case POSITION_INHERIT:
2569 str = (gchar *) "position-inherit";
2570 break;
2571 default:
2572 str = (gchar *) "unknown static property";
2573 }
2574 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2575 g_string_append (a_str, str);
2576 return CR_OK;
2577 }
2579 enum CRStatus
2580 cr_style_float_type_to_string (enum CRFloatType a_code,
2581 GString * a_str, guint a_nb_indent)
2582 {
2583 gchar *str = NULL;
2585 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2587 switch (a_code) {
2588 case FLOAT_NONE:
2589 str = (gchar *) "float-none";
2590 break;
2591 case FLOAT_LEFT:
2592 str = (gchar *) "float-left";
2593 break;
2594 case FLOAT_RIGHT:
2595 str = (gchar *) "float-right";
2596 break;
2597 case FLOAT_INHERIT:
2598 str = (gchar *) "float-inherit";
2599 break;
2600 default:
2601 str = (gchar *) "unknown float property value";
2602 break;
2603 }
2604 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2605 g_string_append (a_str, str);
2606 return CR_OK;
2607 }
2609 enum CRStatus
2610 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
2611 GString * a_str, guint a_nb_indent)
2612 {
2613 gchar *str = NULL;
2615 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2617 switch (a_code) {
2618 case WHITE_SPACE_NORMAL:
2619 str = (gchar *) "normal";
2620 break;
2621 case WHITE_SPACE_PRE:
2622 str = (gchar *) "pre";
2623 break;
2624 case WHITE_SPACE_NOWRAP:
2625 str = (gchar *) "nowrap";
2626 break;
2627 case WHITE_SPACE_INHERIT:
2628 str = (gchar *) "inherited";
2629 break;
2630 default:
2631 str = (gchar *) "unknow white space property value";
2632 break;
2633 }
2634 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2635 g_string_append (a_str, str);
2636 return CR_OK;
2637 }
2639 /**
2640 *Serializes in instance of #CRStyle into
2641 *a string
2642 *@param a_this the instance of #CRStyle to serialize
2643 *@param a_str the string to serialise the style into.
2644 *if *a_str is NULL, a new GString is instanciated, otherwise
2645 *the style serialisation is appended to the existed *a_str
2646 *@param the number of white space char to use for indentation.
2647 *@return CR_OK upon successful completion, an error code otherwise.
2648 */
2649 enum CRStatus
2650 cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
2651 {
2652 const gint INTERNAL_INDENT = 2;
2653 gint indent = a_nb_indent + INTERNAL_INDENT;
2654 gchar *tmp_str = NULL;
2655 GString *str = NULL;
2656 gint i = 0;
2658 g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
2660 if (!*a_str) {
2661 str = g_string_new (NULL);
2662 } else {
2663 str = *a_str;
2664 }
2665 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2666 g_string_append (str, "style {\n");
2668 /*loop over the num_props and to_string() them */
2669 for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
2670 /*
2671 *to_string() the name of the num_prop
2672 *(using num_prop_code_to_string)
2673 *before outputing it value
2674 */
2675 cr_utils_dump_n_chars2 (' ', str, indent);
2676 tmp_str = (gchar *) num_prop_code_to_string ((CRNumProp)i);
2677 if (tmp_str) {
2678 g_string_append_printf (str, "%s: ", tmp_str);
2679 } else {
2680 g_string_append (str, "NULL");
2681 }
2682 tmp_str = NULL;
2683 cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
2684 a_nb_indent +
2685 INTERNAL_INDENT);
2686 g_string_append (str, "\n");
2687 }
2688 /*loop over the rgb_props and to_string() them all */
2689 for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
2690 tmp_str = (gchar *) rgb_prop_code_to_string ((CRRgbProp)i);
2691 cr_utils_dump_n_chars2 (' ', str, indent);
2692 if (tmp_str) {
2693 g_string_append_printf (str, "%s: ", tmp_str);
2694 } else {
2695 g_string_append (str, "NULL: ");
2696 }
2697 tmp_str = NULL;
2698 cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
2699 a_nb_indent +
2700 INTERNAL_INDENT);
2701 g_string_append (str, "\n");
2702 }
2703 /*loop over the border_style_props and to_string() them */
2704 for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
2705 tmp_str = (gchar *)
2706 border_style_prop_code_to_string ((CRBorderStyleProp)i);
2707 cr_utils_dump_n_chars2 (' ', str, indent);
2708 if (tmp_str) {
2709 g_string_append_printf (str, "%s: ", tmp_str);
2710 } else {
2711 g_string_append (str, "NULL: ");
2712 }
2713 tmp_str = NULL;
2714 cr_style_border_style_to_string (a_this->
2715 border_style_props[i], str,
2716 0);
2717 g_string_append (str, "\n");
2718 }
2719 cr_utils_dump_n_chars2 (' ', str, indent);
2720 g_string_append (str, "display: ");
2721 cr_style_display_type_to_string (a_this->display, str, 0);
2722 g_string_append (str, "\n");
2724 cr_utils_dump_n_chars2 (' ', str, indent);
2725 g_string_append (str, "position: ");
2726 cr_style_position_type_to_string (a_this->position, str, 0);
2727 g_string_append (str, "\n");
2729 cr_utils_dump_n_chars2 (' ', str, indent);
2730 g_string_append (str, "float-type: ");
2731 cr_style_float_type_to_string (a_this->float_type, str, 0);
2732 g_string_append (str, "\n");
2734 cr_utils_dump_n_chars2 (' ', str, indent);
2735 g_string_append (str, "white-space: ");
2736 cr_style_white_space_type_to_string (a_this->white_space, str, 0);
2737 g_string_append (str, "\n");
2739 cr_utils_dump_n_chars2 (' ', str, indent);
2740 g_string_append (str, "font-family: ");
2741 tmp_str = (gchar *)cr_font_family_to_string (a_this->font_family, TRUE);
2742 if (tmp_str) {
2743 g_string_append (str, tmp_str);
2744 g_free (tmp_str);
2745 tmp_str = NULL;
2746 } else {
2747 g_string_append (str, "NULL");
2748 }
2749 g_string_append (str, "\n");
2751 cr_utils_dump_n_chars2 (' ', str, indent);
2752 tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
2753 if (tmp_str) {
2754 g_string_append_printf (str, "font-size {sv:%s, ",
2755 tmp_str) ;
2756 } else {
2757 g_string_append (str, "font-size {sv:NULL, ");
2758 }
2759 tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
2760 if (tmp_str) {
2761 g_string_append_printf (str, "cv:%s, ", tmp_str);
2762 } else {
2763 g_string_append (str, "cv:NULL, ");
2764 }
2765 tmp_str = cr_font_size_to_string (&a_this->font_size.av);
2766 if (tmp_str) {
2767 g_string_append_printf (str, "av:%s}", tmp_str);
2768 } else {
2769 g_string_append (str, "av:NULL}");
2770 }
2772 tmp_str = NULL;
2773 g_string_append (str, "\n");
2775 cr_utils_dump_n_chars2 (' ', str, indent);
2776 tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
2777 if (tmp_str) {
2778 g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
2779 } else {
2780 g_string_append (str, "font-size-adjust: NULL");
2781 }
2782 tmp_str = NULL;
2783 g_string_append (str, "\n");
2785 cr_utils_dump_n_chars2 (' ', str, indent);
2786 tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
2787 if (tmp_str) {
2788 g_string_append_printf (str, "font-style: %s", tmp_str);
2789 } else {
2790 g_string_append (str, "font-style: NULL");
2791 }
2792 tmp_str = NULL;
2793 g_string_append (str, "\n");
2795 cr_utils_dump_n_chars2 (' ', str, indent);
2796 tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
2797 if (tmp_str) {
2798 g_string_append_printf (str, "font-variant: %s", tmp_str);
2799 } else {
2800 g_string_append (str, "font-variant: NULL");
2801 }
2802 tmp_str = NULL;
2803 g_string_append (str, "\n");
2805 cr_utils_dump_n_chars2 (' ', str, indent);
2806 tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
2807 if (tmp_str) {
2808 g_string_append_printf (str, "font-weight: %s", tmp_str);
2809 } else {
2810 g_string_append (str, "font-weight: NULL");
2811 }
2812 tmp_str = NULL;
2813 g_string_append (str, "\n");
2815 cr_utils_dump_n_chars2 (' ', str, indent);
2816 tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
2817 if (tmp_str) {
2818 g_string_append_printf (str, "font-stretch: %s", tmp_str);
2819 } else {
2820 g_string_append (str, "font-stretch: NULL");
2821 }
2822 tmp_str = NULL;
2823 g_string_append (str, "\n");
2826 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2827 g_string_append (str, "}");
2829 return CR_OK;
2830 }
2832 /**
2833 *Destructor of the #CRStyle class.
2834 *@param a_this the instance to destroy.
2835 */
2836 void
2837 cr_style_destroy (CRStyle * a_this)
2838 {
2839 g_return_if_fail (a_this);
2841 g_free (a_this);
2842 }