1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
2
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 */
25
26 #include <string.h>
27 #include "cr-style.h"
28
29 /**
30 *@file
31 *The definition of the #CRStyle class.
32 */
33
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 };
91
92 typedef struct _CRPropertyDesc CRPropertyDesc;
93
94 struct _CRPropertyDesc {
95 const guchar *name;
96 enum CRPropertyID prop_id;
97 };
98
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, 0}
146 };
147
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;
157
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;
164
165 struct CRNumPropEnumDumpInfo {
166 enum CRNumProp code;
167 const gchar *str;
168 };
169
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 {0, NULL}
189 };
190
191 struct CRRgbPropEnumDumpInfo {
192 enum CRRgbProp code;
193 const gchar *str;
194 };
195
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 {0, NULL}
204 };
205
206 struct CRBorderStylePropEnumDumpInfo {
207 enum CRBorderStyleProp code;
208 const gchar *str;
209
210 };
211
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 {0, NULL}
219 };
220
221 static enum CRStatus
222 cr_style_init_properties (void);
223
224 enum CRDirection {
225 DIR_TOP = 0,
226 DIR_RIGHT,
227 DIR_BOTTOM,
228 DIR_LEFT,
229
230 /*must be the last one */
231 NB_DIRS
232 };
233
234 static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
235
236 static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
237
238 static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
239 a_code);
240
241 static enum CRStatus
242 set_prop_padding_x_from_value (CRStyle * a_style,
243 CRTerm * a_value, enum CRDirection a_dir);
244
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) ;
252
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) ;
260
261 static enum CRStatus
262 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
263 enum CRDirection a_dir);
264
265 static enum CRStatus
266 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
267
268 static enum CRStatus
269 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
270
271 static enum CRStatus
272 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
273 enum CRDirection a_dir);
274
275 static enum CRStatus
276 set_prop_float (CRStyle * a_style, CRTerm * a_value);
277
278 static enum CRStatus
279 set_prop_width (CRStyle * a_style, CRTerm * a_value);
280
281 static enum CRStatus
282 set_prop_color (CRStyle * a_style, CRTerm * a_value);
283
284 static enum CRStatus
285 set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
286
287 static enum CRStatus
288 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
289 enum CRDirection a_dir);
290
291 static enum CRStatus
292 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
293 enum CRDirection a_dir);
294
295 static enum CRStatus
296 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
297
298 static enum CRStatus
299 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
300
301 static enum CRStatus
302 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
303
304 static enum CRStatus
305 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
306
307 static enum CRStatus
308 init_style_font_size_field (CRStyle * a_style);
309
310 static enum CRStatus
311 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
312
313 static enum CRStatus
314 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
315
316 static enum CRStatus
317 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
318
319 static const gchar *
num_prop_code_to_string(enum CRNumProp a_code)320 num_prop_code_to_string (enum CRNumProp a_code)
321 {
322 gint len = sizeof (gv_num_props_dump_infos) /
323 sizeof (struct CRNumPropEnumDumpInfo);
324 if (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 }
341
342 static const gchar *
rgb_prop_code_to_string(enum CRRgbProp a_code)343 rgb_prop_code_to_string (enum CRRgbProp a_code)
344 {
345 gint len = sizeof (gv_rgb_props_dump_infos) /
346 sizeof (struct CRRgbPropEnumDumpInfo);
347
348 if (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 }
365
366 static const gchar *
border_style_prop_code_to_string(enum CRBorderStyleProp a_code)367 border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
368 {
369 gint len = sizeof (gv_border_style_props_dump_infos) /
370 sizeof (struct CRBorderStylePropEnumDumpInfo);
371
372 if (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 }
389
390 static enum CRStatus
cr_style_init_properties(void)391 cr_style_init_properties (void)
392 {
393
394 if (!gv_prop_hash) {
395 gulong i = 0;
396
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 }
402
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 }
411
412 return CR_OK;
413 }
414
415 static enum CRPropertyID
cr_style_get_prop_id(const guchar * a_prop)416 cr_style_get_prop_id (const guchar * a_prop)
417 {
418 gpointer *raw_id = NULL;
419
420 if (!gv_prop_hash) {
421 cr_style_init_properties ();
422 }
423
424 raw_id = g_hash_table_lookup (gv_prop_hash, a_prop);
425 if (!raw_id) {
426 return PROP_ID_NOT_KNOWN;
427 }
428 return GPOINTER_TO_INT (raw_id);
429 }
430
431 static enum CRStatus
set_prop_padding_x_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)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;
437
438 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
439
440 if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
441 return CR_BAD_PARAM_ERROR;
442
443 switch (a_dir) {
444 case DIR_TOP:
445 num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
446 break;
447
448 case DIR_RIGHT:
449 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
450 break;
451
452 case DIR_BOTTOM:
453 num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
454 break;
455
456 case DIR_LEFT:
457 num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
458 break;
459
460 default:
461 return CR_BAD_PARAM_ERROR;
462 }
463
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 ((guchar *) "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 }
476
477 g_return_val_if_fail (a_value->type == TERM_NUMBER
478 && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
479
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 }
496
497 return status;
498 }
499
500 static enum CRStatus
set_prop_border_x_width_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)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;
507
508 g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
509
510 switch (a_dir) {
511 case DIR_TOP:
512 num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
513 break;
514
515 case DIR_RIGHT:
516 num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
517 break;
518
519 case DIR_BOTTOM:
520 num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
521 break;
522
523 case DIR_LEFT:
524 num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
525 break;
526
527 default:
528 return CR_BAD_PARAM_ERROR;
529 break;
530 }
531
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 }
564
565 return status;
566 }
567
568 static enum CRStatus
set_prop_border_width_from_value(CRStyle * a_style,CRTerm * a_value)569 set_prop_border_width_from_value (CRStyle *a_style,
570 CRTerm *a_value)
571 {
572 CRTerm *cur_term = NULL ;
573 enum CRDirection direction = DIR_TOP ;
574
575 g_return_val_if_fail (a_style && a_value,
576 CR_BAD_PARAM_ERROR) ;
577 cur_term = a_value ;
578
579 if (!cur_term)
580 return CR_ERROR ;
581
582 for (direction = DIR_TOP ;
583 direction < NB_DIRS ; direction ++) {
584 set_prop_border_x_width_from_value (a_style,
585 cur_term,
586 direction) ;
587 }
588
589 cur_term = cur_term->next ;
590 if (!cur_term)
591 return CR_OK ;
592 set_prop_border_x_width_from_value (a_style, cur_term,
593 DIR_RIGHT) ;
594 set_prop_border_x_width_from_value (a_style, cur_term,
595 DIR_LEFT) ;
596
597 cur_term = cur_term->next ;
598 if (!cur_term)
599 return CR_OK ;
600 set_prop_border_x_width_from_value (a_style, cur_term,
601 DIR_BOTTOM) ;
602
603 cur_term = cur_term->next ;
604 if (!cur_term)
605 return CR_OK ;
606 set_prop_border_x_width_from_value (a_style, cur_term,
607 DIR_LEFT) ;
608
609 return CR_OK ;
610 }
611
612 static enum CRStatus
set_prop_border_x_style_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)613 set_prop_border_x_style_from_value (CRStyle * a_style,
614 CRTerm * a_value, enum CRDirection a_dir)
615 {
616 enum CRStatus status = CR_OK;
617 enum CRBorderStyle *border_style_ptr = NULL;
618
619 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
620
621 switch (a_dir) {
622 case DIR_TOP:
623 border_style_ptr = &a_style->
624 border_style_props[BORDER_STYLE_PROP_TOP];
625 break;
626
627 case DIR_RIGHT:
628 border_style_ptr =
629 &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
630 break;
631
632 case DIR_BOTTOM:
633 border_style_ptr = &a_style->
634 border_style_props[BORDER_STYLE_PROP_BOTTOM];
635 break;
636
637 case DIR_LEFT:
638 border_style_ptr = &a_style->
639 border_style_props[BORDER_STYLE_PROP_LEFT];
640 break;
641
642 default:
643 break;
644 }
645
646 if (a_value->type != TERM_IDENT || !a_value->content.str) {
647 return CR_UNKNOWN_TYPE_ERROR;
648 }
649
650 if (!strncmp ("none",
651 a_value->content.str->stryng->str,
652 sizeof ("none")-1)) {
653 *border_style_ptr = BORDER_STYLE_NONE;
654 } else if (!strncmp ("hidden",
655 a_value->content.str->stryng->str,
656 sizeof ("hidden")-1)) {
657 *border_style_ptr = BORDER_STYLE_HIDDEN;
658 } else if (!strncmp ("dotted",
659 a_value->content.str->stryng->str,
660 sizeof ("dotted")-1)) {
661 *border_style_ptr = BORDER_STYLE_DOTTED;
662 } else if (!strncmp ("dashed",
663 a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
664 *border_style_ptr = BORDER_STYLE_DASHED;
665 } else if (!strncmp ("solid",
666 a_value->content.str->stryng->str, sizeof ("solid")-1)) {
667 *border_style_ptr = BORDER_STYLE_SOLID;
668 } else if (!strncmp ("double",
669 a_value->content.str->stryng->str, sizeof ("double")-1)) {
670 *border_style_ptr = BORDER_STYLE_DOUBLE;
671 } else if (!strncmp ("groove",
672 a_value->content.str->stryng->str, sizeof ("groove")-1)) {
673 *border_style_ptr = BORDER_STYLE_GROOVE;
674 } else if (!strncmp ("ridge",
675 a_value->content.str->stryng->str,
676 sizeof ("ridge")-1)) {
677 *border_style_ptr = BORDER_STYLE_RIDGE;
678 } else if (!strncmp ("inset",
679 a_value->content.str->stryng->str,
680 sizeof ("inset")-1)) {
681 *border_style_ptr = BORDER_STYLE_INSET;
682 } else if (!strncmp ("outset",
683 a_value->content.str->stryng->str,
684 sizeof ("outset")-1)) {
685 *border_style_ptr = BORDER_STYLE_OUTSET;
686 } else if (!strncmp ("inherit",
687 a_value->content.str->stryng->str,
688 sizeof ("inherit")-1)) {
689 *border_style_ptr = BORDER_STYLE_INHERIT;
690 } else {
691 status = CR_UNKNOWN_TYPE_ERROR;
692 }
693
694 return status;
695 }
696
697 static enum CRStatus
set_prop_border_style_from_value(CRStyle * a_style,CRTerm * a_value)698 set_prop_border_style_from_value (CRStyle *a_style,
699 CRTerm *a_value)
700 {
701 CRTerm *cur_term = NULL ;
702 enum CRDirection direction = DIR_TOP ;
703
704 g_return_val_if_fail (a_style && a_value,
705 CR_BAD_PARAM_ERROR) ;
706
707 cur_term = a_value ;
708 if (!cur_term || cur_term->type != TERM_IDENT) {
709 return CR_ERROR ;
710 }
711
712 for (direction = DIR_TOP ;
713 direction < NB_DIRS ;
714 direction ++) {
715 set_prop_border_x_style_from_value (a_style,
716 cur_term,
717 direction) ;
718 }
719
720 cur_term = cur_term->next ;
721 if (!cur_term || cur_term->type != TERM_IDENT) {
722 return CR_OK ;
723 }
724
725 set_prop_border_x_style_from_value (a_style, cur_term,
726 DIR_RIGHT) ;
727 set_prop_border_x_style_from_value (a_style, cur_term,
728 DIR_LEFT) ;
729
730 cur_term = cur_term->next ;
731 if (!cur_term || cur_term->type != TERM_IDENT) {
732 return CR_OK ;
733 }
734 set_prop_border_x_style_from_value (a_style, cur_term,
735 DIR_BOTTOM) ;
736
737 cur_term = cur_term->next ;
738 if (!cur_term || cur_term->type != TERM_IDENT) {
739 return CR_OK ;
740 }
741 set_prop_border_x_style_from_value (a_style, cur_term,
742 DIR_LEFT) ;
743 return CR_OK ;
744 }
745
746 static enum CRStatus
set_prop_margin_x_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)747 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
748 enum CRDirection a_dir)
749 {
750 enum CRStatus status = CR_OK;
751 CRNum *num_val = NULL;
752
753 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
754
755 switch (a_dir) {
756 case DIR_TOP:
757 num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
758 break;
759
760 case DIR_RIGHT:
761 num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
762 break;
763
764 case DIR_BOTTOM:
765 num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
766 break;
767
768 case DIR_LEFT:
769 num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
770 break;
771
772 default:
773 break;
774 }
775
776 switch (a_value->type) {
777 case TERM_IDENT:
778 if (a_value->content.str
779 && a_value->content.str->stryng
780 && a_value->content.str->stryng->str
781 && !strcmp (a_value->content.str->stryng->str,
782 "inherit")) {
783 status = cr_num_set (num_val, 0.0, NUM_INHERIT);
784 } else if (a_value->content.str
785 && a_value->content.str->stryng
786 && !strcmp (a_value->content.str->stryng->str,
787 "auto")) {
788 status = cr_num_set (num_val, 0.0, NUM_AUTO);
789 } else {
790 status = CR_UNKNOWN_TYPE_ERROR;
791 }
792 break ;
793
794 case TERM_NUMBER:
795 status = cr_num_copy (num_val, a_value->content.num);
796 break;
797
798 default:
799 status = CR_UNKNOWN_TYPE_ERROR;
800 break;
801 }
802
803 return status;
804 }
805
806 struct CRPropDisplayValPair {
807 const guchar *prop_name;
808 enum CRDisplayType type;
809 };
810
811 static enum CRStatus
set_prop_display_from_value(CRStyle * a_style,CRTerm * a_value)812 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
813 {
814 static const struct CRPropDisplayValPair disp_vals_map[] = {
815 {"none", DISPLAY_NONE},
816 {"inline", DISPLAY_INLINE},
817 {"block", DISPLAY_BLOCK},
818 {"run-in", DISPLAY_RUN_IN},
819 {"compact", DISPLAY_COMPACT},
820 {"marker", DISPLAY_MARKER},
821 {"table", DISPLAY_TABLE},
822 {"inline-table", DISPLAY_INLINE_TABLE},
823 {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
824 {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
825 {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
826 {"table-row", DISPLAY_TABLE_ROW},
827 {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
828 {"table-column", DISPLAY_TABLE_COLUMN},
829 {"table-cell", DISPLAY_TABLE_CELL},
830 {"table-caption", DISPLAY_TABLE_CAPTION},
831 {"inherit", DISPLAY_INHERIT},
832 {NULL, DISPLAY_NONE}
833 };
834
835 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
836
837 switch (a_value->type) {
838 case TERM_IDENT:
839 {
840 int i = 0;
841
842 if (!a_value->content.str
843 || !a_value->content.str->stryng
844 || !a_value->content.str->stryng->str)
845 break;
846
847 for (i = 0; disp_vals_map[i].prop_name; i++) {
848 if (!strncmp
849 (disp_vals_map[i].prop_name,
850 a_value->content.str->stryng->str,
851 strlen (disp_vals_map[i].prop_name))) {
852 a_style->display =
853 disp_vals_map[i].type;
854 break;
855 }
856 }
857 }
858 break;
859
860 default:
861 break;
862 }
863
864 return CR_OK;
865 }
866
867 struct CRPropPositionValPair {
868 const guchar *name;
869 enum CRPositionType type;
870 };
871
872 static enum CRStatus
set_prop_position_from_value(CRStyle * a_style,CRTerm * a_value)873 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
874 {
875 enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
876 static const struct CRPropPositionValPair position_vals_map[] = {
877 {"static", POSITION_STATIC},
878 {"relative", POSITION_RELATIVE},
879 {"absolute", POSITION_ABSOLUTE},
880 {"fixed", POSITION_FIXED},
881 {"inherit", POSITION_INHERIT},
882 {NULL, POSITION_STATIC}
883 /*must alwas be the last one */
884 };
885
886 g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
887
888 switch (a_value->type) {
889 case TERM_IDENT:
890 {
891 int i = 0;
892
893 if (!a_value->content.str
894 || !a_value->content.str->stryng
895 || !a_value->content.str->stryng->str)
896 break;
897
898 for (i = 0; position_vals_map[i].name; i++) {
899 if (!strncmp (position_vals_map[i].name,
900 a_value->content.str->stryng->str,
901 strlen (position_vals_map[i].
902 name))) {
903 a_style->position =
904 position_vals_map[i].type;
905 status = CR_OK;
906 break;
907 }
908 }
909 }
910 break;
911
912 default:
913 break;
914 }
915
916 return CR_OK;
917 }
918
919 static enum CRStatus
set_prop_x_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)920 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
921 enum CRDirection a_dir)
922 {
923 CRNum *box_offset = NULL;
924
925 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
926
927 if (!(a_value->type == TERM_NUMBER)
928 && !(a_value->type == TERM_IDENT)) {
929 return CR_UNKNOWN_PROP_VAL_ERROR;
930 }
931
932 switch (a_dir) {
933 case DIR_TOP:
934 box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
935 break;
936
937 case DIR_RIGHT:
938 box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
939 break;
940
941 case DIR_BOTTOM:
942 box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
943 break;
944 case DIR_LEFT:
945 box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
946 break;
947
948 default:
949 break;
950 }
951
952 box_offset->type = NUM_AUTO;
953
954 if (a_value->type == TERM_NUMBER && a_value->content.num) {
955 cr_num_copy (box_offset, a_value->content.num);
956 } else if (a_value->type == TERM_IDENT
957 && a_value->content.str
958 && a_value->content.str->stryng
959 && a_value->content.str->stryng->str) {
960 if (!strncmp ("inherit",
961 a_value->content.str->stryng->str,
962 sizeof ("inherit")-1)) {
963 cr_num_set (box_offset, 0.0, NUM_INHERIT);
964 } else if (!strncmp ("auto",
965 a_value->content.str->stryng->str,
966 sizeof ("auto")-1)) {
967 box_offset->type = NUM_AUTO;
968 }
969 }
970
971 return CR_OK;
972 }
973
974 static enum CRStatus
set_prop_float(CRStyle * a_style,CRTerm * a_value)975 set_prop_float (CRStyle * a_style, CRTerm * a_value)
976 {
977 g_return_val_if_fail (a_style && a_value,
978 CR_BAD_PARAM_ERROR);
979
980 /*the default float type as specified by the css2 spec */
981 a_style->float_type = FLOAT_NONE;
982
983 if (a_value->type != TERM_IDENT
984 || !a_value->content.str
985 || !a_value->content.str->stryng
986 || !a_value->content.str->stryng->str) {
987 /*unknow type, the float type is set to it's default value */
988 return CR_OK;
989 }
990
991 if (!strncmp ("none",
992 a_value->content.str->stryng->str,
993 sizeof ("none")-1)) {
994 a_style->float_type = FLOAT_NONE;
995 } else if (!strncmp ("left",
996 a_value->content.str->stryng->str,
997 sizeof ("left")-1)) {
998 a_style->float_type = FLOAT_LEFT;
999 } else if (!strncmp ("right",
1000 a_value->content.str->stryng->str,
1001 sizeof ("right")-1)) {
1002 a_style->float_type = FLOAT_RIGHT;
1003 } else if (!strncmp ("inherit",
1004 a_value->content.str->stryng->str,
1005 sizeof ("inherit")-1)) {
1006 a_style->float_type = FLOAT_INHERIT;
1007 }
1008 return CR_OK;
1009 }
1010
1011 static enum CRStatus
set_prop_width(CRStyle * a_style,CRTerm * a_value)1012 set_prop_width (CRStyle * a_style, CRTerm * a_value)
1013 {
1014 CRNum *width = NULL;
1015 g_return_val_if_fail (a_style
1016 && a_value,
1017 CR_BAD_PARAM_ERROR);
1018
1019 width = &a_style->num_props[NUM_PROP_WIDTH].sv;
1020 cr_num_set (width, 0.0, NUM_AUTO);
1021
1022 if (a_value->type == TERM_IDENT) {
1023 if (a_value->content.str
1024 && a_value->content.str->stryng
1025 && a_value->content.str->stryng->str) {
1026 if (!strncmp ("auto",
1027 a_value->content.str->stryng->str,
1028 sizeof ("auto")-1)) {
1029 cr_num_set (width, 0.0, NUM_AUTO);
1030 } else if (!strncmp ("inherit",
1031 a_value->content.str->stryng->str,
1032 sizeof ("inherit")-1)) {
1033 cr_num_set (width, 0.0, NUM_INHERIT);
1034 }
1035 }
1036 } else if (a_value->type == TERM_NUMBER) {
1037 if (a_value->content.num) {
1038 cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
1039 a_value->content.num);
1040 }
1041 }
1042 return CR_OK;
1043 }
1044
1045 static enum CRStatus
set_prop_color(CRStyle * a_style,CRTerm * a_value)1046 set_prop_color (CRStyle * a_style, CRTerm * a_value)
1047 {
1048 enum CRStatus status = CR_OK;
1049 CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
1050
1051 g_return_val_if_fail (a_style
1052 && a_value, CR_BAD_PARAM_ERROR);
1053
1054 status = cr_rgb_set_from_term (a_rgb, a_value);
1055
1056 return status;
1057 }
1058
1059 static enum CRStatus
set_prop_background_color(CRStyle * a_style,CRTerm * a_value)1060 set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
1061 {
1062 enum CRStatus status = CR_OK;
1063 CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
1064
1065 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1066
1067 status = cr_rgb_set_from_term (rgb, a_value);
1068 return status;
1069 }
1070
1071 /**
1072 *Sets border-top-color, border-right-color,
1073 *border-bottom-color or border-left-color properties
1074 *in the style structure. The value is taken from a
1075 *css2 term of type IDENT or RGB.
1076 *@param a_style the style structure to set.
1077 *@param a_value the css2 term to take the color information from.
1078 *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
1079 *@return CR_OK upon successfull completion, an error code otherwise.
1080 */
1081 static enum CRStatus
set_prop_border_x_color_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)1082 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
1083 enum CRDirection a_dir)
1084 {
1085 CRRgb *rgb_color = NULL;
1086 enum CRStatus status = CR_OK;
1087
1088 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1089
1090 switch (a_dir) {
1091 case DIR_TOP:
1092 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
1093 break;
1094
1095 case DIR_RIGHT:
1096 rgb_color =
1097 &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
1098 break;
1099
1100 case DIR_BOTTOM:
1101 rgb_color =
1102 &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
1103 break;
1104
1105 case DIR_LEFT:
1106 rgb_color =
1107 &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
1108 break;
1109
1110 default:
1111 cr_utils_trace_info ("unknown DIR type");
1112 return CR_BAD_PARAM_ERROR;
1113 }
1114
1115 status = CR_UNKNOWN_PROP_VAL_ERROR;
1116
1117 if (a_value->type == TERM_IDENT) {
1118 if (a_value->content.str
1119 && a_value->content.str->stryng
1120 && a_value->content.str->stryng->str) {
1121 status = cr_rgb_set_from_name
1122 (rgb_color,
1123 a_value->content.str->stryng->str);
1124
1125 }
1126 if (status != CR_OK) {
1127 cr_rgb_set_from_name (rgb_color, "black");
1128 }
1129 } else if (a_value->type == TERM_RGB) {
1130 if (a_value->content.rgb) {
1131 status = cr_rgb_set_from_rgb
1132 (rgb_color, a_value->content.rgb);
1133 }
1134 }
1135 return status;
1136 }
1137
1138 static enum CRStatus
set_prop_border_x_from_value(CRStyle * a_style,CRTerm * a_value,enum CRDirection a_dir)1139 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
1140 enum CRDirection a_dir)
1141 {
1142 CRTerm *cur_term = NULL;
1143
1144 enum CRStatus status = CR_OK;
1145
1146 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1147
1148 for (cur_term = a_value;
1149 cur_term;
1150 cur_term = cur_term->next) {
1151 status = set_prop_border_x_width_from_value (a_style,
1152 cur_term, a_dir);
1153
1154 if (status != CR_OK) {
1155 status = set_prop_border_x_style_from_value
1156 (a_style, cur_term, a_dir);
1157 }
1158 if (status != CR_OK) {
1159 status = set_prop_border_x_color_from_value
1160 (a_style, cur_term, a_dir);
1161 }
1162 }
1163 return CR_OK;
1164 }
1165
1166 static enum CRStatus
set_prop_border_from_value(CRStyle * a_style,CRTerm * a_value)1167 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
1168 {
1169 enum CRDirection direction = 0;
1170
1171 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1172
1173 for (direction = 0; direction < NB_DIRS; direction++) {
1174 set_prop_border_x_from_value (a_style,
1175 a_value,
1176 direction);
1177 }
1178
1179 return CR_OK;
1180 }
1181
1182 static enum CRStatus
set_prop_padding_from_value(CRStyle * a_style,CRTerm * a_value)1183 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
1184 {
1185 CRTerm *cur_term = NULL;
1186 enum CRDirection direction = 0;
1187 enum CRStatus status = CR_OK;
1188
1189 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1190
1191 cur_term = a_value;
1192
1193 /*filter the eventual non NUMBER terms some user can have written here*/
1194 while (cur_term && cur_term->type != TERM_NUMBER) {
1195 cur_term = cur_term->next;
1196 }
1197 if (!cur_term)
1198 return CR_ERROR ;
1199
1200 for (direction = 0; direction < NB_DIRS; direction++) {
1201 set_prop_padding_x_from_value (a_style, cur_term, direction);
1202 }
1203 cur_term = cur_term->next;
1204
1205 /*filter non NUMBER terms that some users can have written here...*/
1206 while (cur_term && cur_term->type != TERM_NUMBER) {
1207 cur_term = cur_term->next;
1208 }
1209 /*the user can have just written padding: 1px*/
1210 if (!cur_term)
1211 return CR_OK;
1212
1213 set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
1214 set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1215
1216 while (cur_term && cur_term->type != TERM_NUMBER) {
1217 cur_term = cur_term->next;
1218 }
1219 if (!cur_term)
1220 return CR_OK;
1221
1222 set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
1223
1224 while (cur_term && cur_term->type != TERM_NUMBER) {
1225 cur_term = cur_term->next;
1226 }
1227 if (!cur_term)
1228 return CR_OK;
1229 status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
1230 return status;
1231 }
1232
1233 static enum CRStatus
set_prop_margin_from_value(CRStyle * a_style,CRTerm * a_value)1234 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
1235 {
1236 CRTerm *cur_term = NULL;
1237 enum CRDirection direction = 0;
1238 enum CRStatus status = CR_OK;
1239
1240 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1241
1242 cur_term = a_value;
1243
1244 while (cur_term && cur_term->type != TERM_NUMBER) {
1245 cur_term = cur_term->next;
1246 }
1247
1248 if (!cur_term)
1249 return CR_OK;
1250
1251 for (direction = 0; direction < NB_DIRS; direction++) {
1252 set_prop_margin_x_from_value (a_style, cur_term, direction);
1253 }
1254 cur_term = cur_term->next;
1255
1256 while (cur_term && cur_term->type != TERM_NUMBER) {
1257 cur_term = cur_term->next;
1258 }
1259 if (!cur_term)
1260 return CR_OK;
1261
1262 set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
1263 set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1264
1265 while (cur_term && cur_term->type != TERM_NUMBER) {
1266 cur_term = cur_term->next;
1267 }
1268 if (!cur_term)
1269 return CR_OK;
1270
1271 set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
1272
1273 while (cur_term && cur_term->type != TERM_NUMBER) {
1274 cur_term = cur_term->next;
1275 }
1276 if (!cur_term)
1277 return CR_OK;
1278
1279 status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
1280
1281 return status;
1282 }
1283
1284 static enum CRStatus
set_prop_font_family_from_value(CRStyle * a_style,CRTerm * a_value)1285 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
1286 {
1287 CRTerm *cur_term = NULL;
1288 CRFontFamily *font_family = NULL,
1289 *cur_ff = NULL,
1290 *cur_ff2 = NULL;
1291
1292 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1293
1294 if (a_value->type == TERM_IDENT &&
1295 a_value->content.str &&
1296 a_value->content.str->stryng &&
1297 a_value->content.str->stryng->str &&
1298 !strcmp ("inherit", a_value->content.str->stryng->str))
1299 {
1300 font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
1301 goto out;
1302 }
1303
1304 for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
1305 switch (cur_term->type) {
1306 case TERM_IDENT:
1307 {
1308 enum CRFontFamilyType font_type;
1309
1310 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 "sans-serif")) {
1316 font_type = FONT_FAMILY_SANS_SERIF;
1317 } else if (cur_term->content.str
1318 && cur_term->content.str->stryng
1319 && cur_term->content.str->stryng->str
1320 && !strcmp
1321 (cur_term->content.str->stryng->str,
1322 "serif")) {
1323 font_type = FONT_FAMILY_SERIF;
1324 } else if (cur_term->content.str
1325 && cur_term->content.str->stryng
1326 && cur_term->content.str->stryng->str
1327 && !strcmp (cur_term->content.str->stryng->str,
1328 "cursive")) {
1329 font_type = FONT_FAMILY_CURSIVE;
1330 } else if (cur_term->content.str
1331 && cur_term->content.str->stryng
1332 && cur_term->content.str->stryng->str
1333 && !strcmp (cur_term->content.str->stryng->str,
1334 "fantasy")) {
1335 font_type = FONT_FAMILY_FANTASY;
1336 } else if (cur_term->content.str
1337 && cur_term->content.str->stryng
1338 && cur_term->content.str->stryng->str
1339 && !strcmp (cur_term->content.str->stryng->str,
1340 "monospace")) {
1341 font_type = FONT_FAMILY_MONOSPACE;
1342 } else {
1343 /*
1344 *unknown property value.
1345 *ignore it.
1346 */
1347 continue;
1348 }
1349
1350 cur_ff = cr_font_family_new (font_type, NULL);
1351 }
1352 break;
1353
1354 case TERM_STRING:
1355 {
1356 if (cur_term->content.str
1357 && cur_term->content.str->stryng
1358 && cur_term->content.str->stryng->str) {
1359 cur_ff = cr_font_family_new
1360 (FONT_FAMILY_NON_GENERIC,
1361 cur_term->content.str->stryng->str);
1362 }
1363 }
1364 break;
1365
1366 default:
1367 break;
1368 }
1369
1370 cur_ff2 = cr_font_family_append (font_family, cur_ff);
1371 if (cur_ff2) {
1372 font_family = cur_ff2;
1373 }
1374 }
1375
1376 out:
1377 if (font_family) {
1378 if (a_style->font_family) {
1379 cr_font_family_destroy (a_style->font_family);
1380 a_style->font_family = NULL ;
1381 }
1382 a_style->font_family = font_family;
1383 font_family = NULL ;
1384 }
1385
1386 return CR_OK;
1387 }
1388
1389 static enum CRStatus
init_style_font_size_field(CRStyle * a_style)1390 init_style_font_size_field (CRStyle * a_style)
1391 {
1392 g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
1393
1394 memset (&a_style->font_size, 0,
1395 sizeof (CRFontSizeVal)) ;
1396 /*
1397 if (!a_style->font_size) {
1398 a_style->font_size = cr_font_size_new ();
1399 if (!a_style->font_size) {
1400 return CR_INSTANCIATION_FAILED_ERROR;
1401 }
1402 } else {
1403 cr_font_size_clear (a_style->font_size);
1404 }
1405 */
1406 return CR_OK;
1407 }
1408
1409 static enum CRStatus
set_prop_font_size_from_value(CRStyle * a_style,CRTerm * a_value)1410 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
1411 {
1412 enum CRStatus status = CR_OK;
1413
1414 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1415
1416 switch (a_value->type) {
1417 case TERM_IDENT:
1418 if (a_value->content.str
1419 && a_value->content.str->stryng
1420 && a_value->content.str->stryng->str
1421 && !strcmp (a_value->content.str->stryng->str,
1422 "xx-small")) {
1423 status = init_style_font_size_field (a_style);
1424 g_return_val_if_fail (status == CR_OK, status);
1425
1426 a_style->font_size.sv.type =
1427 PREDEFINED_ABSOLUTE_FONT_SIZE;
1428 a_style->font_size.sv.value.predefined =
1429 FONT_SIZE_XX_SMALL;
1430
1431 } else if (a_value->content.str
1432 && a_value->content.str->stryng
1433 && a_value->content.str->stryng->str
1434 && !strcmp (a_value->content.str->stryng->str,
1435 "x-small")) {
1436 status = init_style_font_size_field (a_style);
1437 g_return_val_if_fail (status == CR_OK, status);
1438
1439 a_style->font_size.sv.type =
1440 PREDEFINED_ABSOLUTE_FONT_SIZE;
1441 a_style->font_size.sv.value.predefined =
1442 FONT_SIZE_X_SMALL;
1443 } else if (a_value->content.str
1444 && a_value->content.str->stryng
1445 && a_value->content.str->stryng->str
1446 && !strcmp (a_value->content.str->stryng->str,
1447 "small")) {
1448 status = init_style_font_size_field (a_style);
1449 g_return_val_if_fail (status == CR_OK, status);
1450
1451 a_style->font_size.sv.type =
1452 PREDEFINED_ABSOLUTE_FONT_SIZE;
1453 a_style->font_size.sv.value.predefined =
1454 FONT_SIZE_SMALL;
1455 } else if (a_value->content.str
1456 && a_value->content.str->stryng
1457 && a_value->content.str->stryng->str
1458 && !strcmp (a_value->content.str->stryng->str, "medium")) {
1459 status = init_style_font_size_field (a_style);
1460 g_return_val_if_fail (status == CR_OK, status);
1461
1462 a_style->font_size.sv.type =
1463 PREDEFINED_ABSOLUTE_FONT_SIZE;
1464 a_style->font_size.sv.value.predefined =
1465 FONT_SIZE_MEDIUM;
1466 } else if (a_value->content.str
1467 && a_value->content.str->stryng
1468 && a_value->content.str->stryng->str
1469 && !strcmp (a_value->content.str->stryng->str,
1470 "large")) {
1471 status = init_style_font_size_field (a_style);
1472 g_return_val_if_fail (status == CR_OK, status);
1473
1474 a_style->font_size.sv.type =
1475 PREDEFINED_ABSOLUTE_FONT_SIZE;
1476 a_style->font_size.sv.value.predefined =
1477 FONT_SIZE_LARGE;
1478 } else if (a_value->content.str
1479 && a_value->content.str->stryng
1480 && a_value->content.str->stryng->str
1481 && !strcmp (a_value->content.str->stryng->str,
1482 "x-large")) {
1483 status = init_style_font_size_field (a_style);
1484 g_return_val_if_fail (status == CR_OK, status);
1485
1486 a_style->font_size.sv.type =
1487 PREDEFINED_ABSOLUTE_FONT_SIZE;
1488 a_style->font_size.sv.value.predefined =
1489 FONT_SIZE_X_LARGE;
1490 } else if (a_value->content.str
1491 && a_value->content.str->stryng
1492 && a_value->content.str->stryng->str
1493 && !strcmp (a_value->content.str->stryng->str,
1494 "xx-large")) {
1495 status = init_style_font_size_field (a_style);
1496 g_return_val_if_fail (status == CR_OK, status);
1497
1498 a_style->font_size.sv.type =
1499 PREDEFINED_ABSOLUTE_FONT_SIZE;
1500 a_style->font_size.sv.value.predefined =
1501 FONT_SIZE_XX_LARGE;
1502 } else if (a_value->content.str
1503 && a_value->content.str->stryng
1504 && a_value->content.str->stryng->str
1505 && !strcmp (a_value->content.str->stryng->str,
1506 "larger")) {
1507 status = init_style_font_size_field (a_style);
1508 g_return_val_if_fail (status == CR_OK, status);
1509
1510 a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1511 a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
1512 } else if (a_value->content.str
1513 && a_value->content.str->stryng
1514 && a_value->content.str->stryng->str
1515 && !strcmp (a_value->content.str->stryng->str,
1516 "smaller")) {
1517 status = init_style_font_size_field (a_style);
1518 g_return_val_if_fail (status == CR_OK, status);
1519
1520 a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
1521 a_style->font_size.sv.value.relative =
1522 FONT_SIZE_SMALLER;
1523 } else if (a_value->content.str
1524 && a_value->content.str->stryng
1525 && a_value->content.str->stryng->str
1526 && !strcmp (a_value->content.str->stryng->str, "inherit")) {
1527 status = init_style_font_size_field (a_style);
1528 g_return_val_if_fail (status == CR_OK, status);
1529 a_style->font_size.sv.type = INHERITED_FONT_SIZE;
1530
1531 } else {
1532 cr_utils_trace_info ("Unknow value of font-size") ;
1533 status = init_style_font_size_field (a_style);
1534 return CR_UNKNOWN_PROP_VAL_ERROR;
1535 }
1536 break;
1537
1538 case TERM_NUMBER:
1539 if (a_value->content.num) {
1540 status = init_style_font_size_field (a_style);
1541 g_return_val_if_fail (status == CR_OK, status);
1542
1543 a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE;
1544 cr_num_copy (&a_style->font_size.sv.value.absolute,
1545 a_value->content.num) ;
1546 }
1547 break;
1548
1549 default:
1550 status = init_style_font_size_field (a_style);
1551 return CR_UNKNOWN_PROP_VAL_ERROR;
1552 }
1553 return CR_OK;
1554 }
1555
1556 static enum CRStatus
set_prop_font_style_from_value(CRStyle * a_style,CRTerm * a_value)1557 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
1558 {
1559 enum CRStatus status = CR_OK;
1560
1561 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1562
1563 switch (a_value->type) {
1564 case TERM_IDENT:
1565 if (a_value->content.str
1566 && a_value->content.str->stryng
1567 && a_value->content.str->stryng->str) {
1568 if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1569 a_style->font_style = FONT_STYLE_NORMAL;
1570 } else if (!strcmp
1571 (a_value->content.str->stryng->str,
1572 "italic")) {
1573 a_style->font_style = FONT_STYLE_ITALIC;
1574 } else if (!strcmp
1575 (a_value->content.str->stryng->str,
1576 "oblique")) {
1577 a_style->font_style = FONT_STYLE_OBLIQUE;
1578 } else if (!strcmp
1579 (a_value->content.str->stryng->str,
1580 "inherit")) {
1581 a_style->font_style = FONT_STYLE_INHERIT;
1582 } else {
1583 status = CR_UNKNOWN_PROP_VAL_ERROR;
1584 }
1585 }
1586 break;
1587
1588 default:
1589 status = CR_UNKNOWN_PROP_VAL_ERROR;
1590 break;
1591 }
1592
1593 return status;
1594 }
1595
1596 static enum CRStatus
set_prop_font_weight_from_value(CRStyle * a_style,CRTerm * a_value)1597 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
1598 {
1599 enum CRStatus status = CR_OK;
1600
1601 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1602
1603 switch (a_value->type) {
1604 case TERM_IDENT:
1605 if (a_value->content.str
1606 && a_value->content.str->stryng
1607 && a_value->content.str->stryng->str) {
1608 if (!strcmp (a_value->content.str->stryng->str,
1609 "normal")) {
1610 a_style->font_weight = FONT_WEIGHT_NORMAL;
1611 } else if (!strcmp (a_value->content.str->stryng->str,
1612 "bold")) {
1613 a_style->font_weight = FONT_WEIGHT_BOLD;
1614 } else if (!strcmp (a_value->content.str->stryng->str,
1615 "bolder")) {
1616 a_style->font_weight = FONT_WEIGHT_BOLDER;
1617 } else if (!strcmp (a_value->content.str->stryng->str,
1618 "lighter")) {
1619 a_style->font_weight = FONT_WEIGHT_LIGHTER;
1620 } else if (!strcmp (a_value->content.str->stryng->str,
1621 "inherit")) {
1622 a_style->font_weight = FONT_WEIGHT_INHERIT;
1623
1624 } else {
1625 status = CR_UNKNOWN_PROP_VAL_ERROR;
1626 }
1627
1628 }
1629 break;
1630
1631 case TERM_NUMBER:
1632 if (a_value->content.num
1633 && (a_value->content.num->type == NUM_GENERIC
1634 || a_value->content.num->type == NUM_AUTO)) {
1635 if (a_value->content.num->val <= 150) {
1636 a_style->font_weight = FONT_WEIGHT_100;
1637 } else if (a_value->content.num->val <= 250) {
1638 a_style->font_weight = FONT_WEIGHT_200;
1639 } else if (a_value->content.num->val <= 350) {
1640 a_style->font_weight = FONT_WEIGHT_300;
1641 } else if (a_value->content.num->val <= 450) {
1642 a_style->font_weight = FONT_WEIGHT_400;
1643 } else if (a_value->content.num->val <= 550) {
1644 a_style->font_weight = FONT_WEIGHT_500;
1645 } else if (a_value->content.num->val <= 650) {
1646 a_style->font_weight = FONT_WEIGHT_600;
1647 } else if (a_value->content.num->val <= 750) {
1648 a_style->font_weight = FONT_WEIGHT_700;
1649 } else if (a_value->content.num->val <= 850) {
1650 a_style->font_weight = FONT_WEIGHT_800;
1651 } else {
1652 a_style->font_weight = FONT_WEIGHT_900;
1653 }
1654 }
1655 break;
1656
1657 default:
1658 status = CR_UNKNOWN_PROP_VAL_ERROR;
1659 break;
1660 }
1661
1662 return status;
1663 }
1664
1665 static enum CRStatus
set_prop_white_space_from_value(CRStyle * a_style,CRTerm * a_value)1666 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
1667 {
1668 enum CRStatus status = CR_OK;
1669
1670 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
1671
1672 switch (a_value->type) {
1673 case TERM_IDENT:
1674 if (a_value->content.str && a_value->content.str->stryng) {
1675 if (!strcmp (a_value->content.str->stryng->str, "normal")) {
1676 a_style->white_space = WHITE_SPACE_NORMAL;
1677 } else if (!strcmp (a_value->content.str->stryng->str,
1678 "pre")) {
1679 a_style->font_weight = WHITE_SPACE_PRE;
1680 } else if (!strcmp (a_value->content.str->stryng->str,
1681 "nowrap")) {
1682 a_style->white_space = WHITE_SPACE_NOWRAP;
1683 } else if (!strcmp (a_value->content.str->stryng->str,
1684 "inherit")) {
1685 a_style->white_space = WHITE_SPACE_INHERIT;
1686 } else {
1687 status = CR_UNKNOWN_PROP_VAL_ERROR;
1688 }
1689 }
1690 break;
1691 default:
1692 status = CR_UNKNOWN_PROP_VAL_ERROR;
1693 break;
1694 }
1695
1696 return status;
1697 }
1698
1699 /******************
1700 *Public methods
1701 ******************/
1702
1703 /**
1704 *Default constructor of #CRStyle.
1705 *@param a_set_props_to_initial_values if TRUE, the style properties
1706 *will be set to the default values. Only the style properties of the
1707 *root box should be set to their initial values.
1708 *Otherwise, the style values are set to their default value.
1709 *Read the CSS2 spec, chapters 6.1.1 to 6.2.
1710 */
1711 CRStyle *
cr_style_new(gboolean a_set_props_to_initial_values)1712 cr_style_new (gboolean a_set_props_to_initial_values)
1713 {
1714 CRStyle *result = NULL;
1715
1716 result = g_try_malloc (sizeof (CRStyle));
1717 if (!result) {
1718 cr_utils_trace_info ("Out of memory");
1719 return NULL;
1720 }
1721 memset (result, 0, sizeof (CRStyle));
1722 gv_prop_hash_ref_count++;
1723
1724 if (a_set_props_to_initial_values == TRUE) {
1725 cr_style_set_props_to_initial_values (result);
1726 } else {
1727 cr_style_set_props_to_default_values (result);
1728 }
1729
1730 return result;
1731 }
1732
1733 /**
1734 *Sets the style properties to their default values according to the css2 spec
1735 * i.e inherit if the property is inherited, its initial value otherwise.
1736 *@param a_this the current instance of #CRStyle.
1737 *@return CR_OK upon successfull completion, an error code otherwise.
1738 */
1739 enum CRStatus
cr_style_set_props_to_default_values(CRStyle * a_this)1740 cr_style_set_props_to_default_values (CRStyle * a_this)
1741 {
1742 glong i = 0;
1743
1744 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1745
1746 for (i = 0; i < NB_NUM_PROPS; i++)
1747 {
1748 switch (i)
1749 {
1750 case NUM_PROP_WIDTH:
1751 case NUM_PROP_TOP:
1752 case NUM_PROP_RIGHT:
1753 case NUM_PROP_BOTTOM:
1754 case NUM_PROP_LEFT:
1755 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1756 break;
1757
1758 case NUM_PROP_PADDING_TOP:
1759 case NUM_PROP_PADDING_RIGHT:
1760 case NUM_PROP_PADDING_BOTTOM:
1761 case NUM_PROP_PADDING_LEFT:
1762 case NUM_PROP_BORDER_TOP:
1763 case NUM_PROP_BORDER_RIGHT:
1764 case NUM_PROP_BORDER_BOTTOM:
1765 case NUM_PROP_BORDER_LEFT:
1766 case NUM_PROP_MARGIN_TOP:
1767 case NUM_PROP_MARGIN_RIGHT:
1768 case NUM_PROP_MARGIN_BOTTOM:
1769 case NUM_PROP_MARGIN_LEFT:
1770 cr_num_set (&a_this->num_props[i].sv,
1771 0, NUM_LENGTH_PX);
1772 break;
1773
1774 default:
1775 cr_utils_trace_info ("Unknown property");
1776 break;
1777 }
1778 }
1779
1780 for (i = 0; i < NB_RGB_PROPS; i++) {
1781
1782 switch (i) {
1783 /*default foreground color is black */
1784 case RGB_PROP_COLOR:
1785 /*
1786 *REVIEW: color is inherited and the default value is
1787 *ua dependant.
1788 */
1789 cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
1790 TRUE) ;
1791 break;
1792
1793 /*default background color is white */
1794 case RGB_PROP_BACKGROUND_COLOR:
1795 /* TODO: the default value should be transparent */
1796 cr_rgb_set (&a_this->rgb_props[i].sv,
1797 255, 255, 255, FALSE);
1798 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1799 TRUE) ;
1800 break;
1801
1802 default:
1803 /*
1804 *TODO: for BORDER_COLOR the initial value should
1805 * be the same as COLOR
1806 */
1807 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
1808 FALSE);
1809 break;
1810 }
1811 }
1812
1813 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1814 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1815 }
1816
1817 a_this->display = DISPLAY_INLINE;
1818 a_this->position = POSITION_STATIC;
1819 a_this->float_type = FLOAT_NONE;
1820 a_this->parent_style = NULL;
1821 a_this->font_style = FONT_STYLE_INHERIT;
1822 a_this->font_variant = FONT_VARIANT_INHERIT;
1823 a_this->font_weight = FONT_WEIGHT_INHERIT;
1824 a_this->font_family = NULL;
1825
1826 cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
1827 cr_font_size_clear (&a_this->font_size.cv) ;
1828 cr_font_size_clear (&a_this->font_size.av) ;
1829
1830 /* To make the inheritance resolution possible and efficient */
1831 a_this->inherited_props_resolved = FALSE ;
1832 return CR_OK;
1833 }
1834
1835 /**
1836 *Sets the style properties to their initial value according to the css2 spec.
1837 *This function should be used to initialize the style of the root element
1838 *of an xml tree.
1839 *Some properties are user agent dependant like font-family, and
1840 *are not initialized, read the spec to make you renderer compliant.
1841 *@param a_this the current instance of #CRStyle.
1842 *@return CR_OK upon successfull completion, an error code otherwise.
1843 */
1844 enum CRStatus
cr_style_set_props_to_initial_values(CRStyle * a_this)1845 cr_style_set_props_to_initial_values (CRStyle *a_this)
1846 {
1847 glong i = 0;
1848
1849 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1850
1851 for (i = 0; i < NB_NUM_PROPS; i++) {
1852 switch (i) {
1853 case NUM_PROP_WIDTH:
1854 cr_num_set (&a_this->num_props[i].sv, 800,
1855 NUM_LENGTH_PX) ;
1856 break ;
1857 case NUM_PROP_TOP:
1858 case NUM_PROP_RIGHT:
1859 case NUM_PROP_BOTTOM:
1860 case NUM_PROP_LEFT:
1861 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
1862 break;
1863
1864 case NUM_PROP_PADDING_TOP:
1865 case NUM_PROP_PADDING_RIGHT:
1866 case NUM_PROP_PADDING_BOTTOM:
1867 case NUM_PROP_PADDING_LEFT:
1868 case NUM_PROP_BORDER_TOP:
1869 case NUM_PROP_BORDER_RIGHT:
1870 case NUM_PROP_BORDER_BOTTOM:
1871 case NUM_PROP_BORDER_LEFT:
1872 case NUM_PROP_MARGIN_TOP:
1873 case NUM_PROP_MARGIN_RIGHT:
1874 case NUM_PROP_MARGIN_BOTTOM:
1875 case NUM_PROP_MARGIN_LEFT:
1876 cr_num_set (&a_this->num_props[i].sv,
1877 0, NUM_LENGTH_PX);
1878 break;
1879
1880 default:
1881 cr_utils_trace_info ("Unknown property");
1882 break;
1883 }
1884 }
1885
1886 for (i = 0; i < NB_RGB_PROPS; i++) {
1887
1888 switch (i) {
1889 /*default foreground color is black */
1890 case RGB_PROP_COLOR:
1891 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1892 break;
1893
1894 /*default background color is white */
1895 case RGB_PROP_BACKGROUND_COLOR:
1896 cr_rgb_set (&a_this->rgb_props[i].sv,
1897 255, 255, 255, FALSE);
1898 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
1899 TRUE) ;
1900 break;
1901 default:
1902 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
1903 break;
1904 }
1905 }
1906
1907 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1908 a_this->border_style_props[i] = BORDER_STYLE_NONE;
1909 }
1910
1911 a_this->display = DISPLAY_BLOCK;
1912 a_this->position = POSITION_STATIC;
1913 a_this->float_type = FLOAT_NONE;
1914 a_this->font_style = FONT_STYLE_NORMAL;
1915 a_this->font_variant = FONT_VARIANT_NORMAL;
1916 a_this->font_weight = FONT_WEIGHT_NORMAL;
1917 a_this->font_stretch = FONT_STRETCH_NORMAL;
1918 a_this->white_space = WHITE_SPACE_NORMAL;
1919 cr_font_size_set_predefined_absolute_font_size
1920 (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
1921 a_this->inherited_props_resolved = FALSE ;
1922
1923 return CR_OK;
1924 }
1925
1926 /**
1927 *Resolves the inherited properties.
1928 *The function sets the "inherited" properties to either the value of
1929 *their parent properties.
1930 *This function is *NOT* recursive. So the inherited properties of
1931 *the parent style must have been resolved prior to calling this function.
1932 *@param a_this the instance where
1933 *@return CR_OK if a root node is found and the propagation is successful,
1934 *an error code otherwise
1935 */
1936 enum CRStatus
cr_style_resolve_inherited_properties(CRStyle * a_this)1937 cr_style_resolve_inherited_properties (CRStyle *a_this)
1938 {
1939 enum CRStatus ret = CR_OK;
1940 glong i = 0;
1941
1942 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
1943 g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
1944
1945 if (a_this->inherited_props_resolved == TRUE)
1946 return CR_OK ;
1947
1948 for (i=0 ; i < NB_NUM_PROPS ;i++) {
1949 if (a_this->num_props[i].sv.type == NUM_INHERIT) {
1950 cr_num_copy (&a_this->num_props[i].cv,
1951 &a_this->parent_style->num_props[i].cv);
1952 }
1953 }
1954 for (i=0; i < NB_RGB_PROPS; i++) {
1955 if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
1956 cr_rgb_copy (
1957 &a_this->rgb_props[i].cv,
1958 &a_this->parent_style->rgb_props[i].cv);
1959 }
1960 }
1961 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
1962 if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
1963 a_this->border_style_props[i] =
1964 a_this->parent_style->border_style_props[i];
1965 }
1966 }
1967
1968 if (a_this->display == DISPLAY_INHERIT) {
1969 a_this->display = a_this->parent_style->display;
1970 }
1971 if (a_this->position == POSITION_INHERIT) {
1972 a_this->position = a_this->parent_style->position;
1973 }
1974 if (a_this->float_type == FLOAT_INHERIT) {
1975 a_this->float_type = a_this->parent_style->float_type;
1976 }
1977 if (a_this->font_style == FONT_STYLE_INHERIT) {
1978 a_this->font_style = a_this->parent_style->font_style;
1979 }
1980 if (a_this->font_variant == FONT_VARIANT_INHERIT) {
1981 a_this->font_variant = a_this->parent_style->font_variant;
1982 }
1983 if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
1984 a_this->font_weight = a_this->parent_style->font_weight;
1985 }
1986 if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
1987 a_this->font_stretch = a_this->parent_style->font_stretch;
1988 }
1989 /*NULL is inherit marker for font_famiy*/
1990 if (a_this->font_family == NULL) {
1991 a_this->font_family = a_this->parent_style->font_family;
1992 }
1993 if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
1994 cr_font_size_copy (&a_this->font_size.cv,
1995 &a_this->parent_style->font_size.cv) ;
1996 }
1997 a_this->inherited_props_resolved = TRUE ;
1998 return ret;
1999 }
2000
2001 /**
2002 *Walks through a css2 property declaration, and populated the
2003 *according field(s) in the #CRStyle structure.
2004 *If the properties or their value(s) are/is not known,
2005 *sets the corresponding field(s) of #CRStyle to its/their default
2006 *value(s)
2007 *@param a_this the instance of #CRStyle to set.
2008 *@param a_decl the declaration from which the #CRStyle fields are set.
2009 *@return CR_OK upon successfull completion, an error code otherwise.
2010 */
2011 enum CRStatus
cr_style_set_style_from_decl(CRStyle * a_this,CRDeclaration * a_decl)2012 cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl)
2013 {
2014 CRTerm *value = NULL;
2015 enum CRStatus status = CR_OK;
2016
2017 enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN;
2018
2019 g_return_val_if_fail (a_this && a_decl
2020 && a_decl
2021 && a_decl->property
2022 && a_decl->property->stryng
2023 && a_decl->property->stryng->str,
2024 CR_BAD_PARAM_ERROR);
2025
2026 prop_id = cr_style_get_prop_id
2027 (a_decl->property->stryng->str);
2028
2029 value = a_decl->value;
2030 switch (prop_id) {
2031 case PROP_ID_PADDING_TOP:
2032 status = set_prop_padding_x_from_value
2033 (a_this, value, DIR_TOP);
2034 break;
2035
2036 case PROP_ID_PADDING_RIGHT:
2037 status = set_prop_padding_x_from_value
2038 (a_this, value, DIR_RIGHT);
2039 break;
2040 case PROP_ID_PADDING_BOTTOM:
2041 status = set_prop_padding_x_from_value
2042 (a_this, value, DIR_BOTTOM);
2043 break;
2044
2045 case PROP_ID_PADDING_LEFT:
2046 status = set_prop_padding_x_from_value
2047 (a_this, value, DIR_LEFT);
2048 break;
2049
2050 case PROP_ID_PADDING:
2051 status = set_prop_padding_from_value (a_this, value) ;
2052 break;
2053
2054 case PROP_ID_BORDER_TOP_WIDTH:
2055 status = set_prop_border_x_width_from_value (a_this, value,
2056 DIR_TOP);
2057 break;
2058
2059 case PROP_ID_BORDER_RIGHT_WIDTH:
2060 status = set_prop_border_x_width_from_value (a_this, value,
2061 DIR_RIGHT);
2062 break;
2063
2064 case PROP_ID_BORDER_BOTTOM_WIDTH:
2065 status = set_prop_border_x_width_from_value (a_this, value,
2066 DIR_BOTTOM);
2067 break;
2068
2069 case PROP_ID_BORDER_LEFT_WIDTH:
2070 status = set_prop_border_x_width_from_value (a_this, value,
2071 DIR_LEFT);
2072 break;
2073
2074 case PROP_ID_BORDER_WIDTH:
2075 status = set_prop_border_width_from_value (a_this, value) ;
2076 break ;
2077
2078 case PROP_ID_BORDER_TOP_STYLE:
2079 status = set_prop_border_x_style_from_value (a_this, value,
2080 DIR_TOP);
2081 break;
2082
2083 case PROP_ID_BORDER_RIGHT_STYLE:
2084 status = set_prop_border_x_style_from_value (a_this, value,
2085 DIR_RIGHT);
2086 break;
2087
2088 case PROP_ID_BORDER_BOTTOM_STYLE:
2089 status = set_prop_border_x_style_from_value (a_this, value,
2090 DIR_BOTTOM);
2091 break;
2092
2093 case PROP_ID_BORDER_LEFT_STYLE:
2094 status = set_prop_border_x_style_from_value (a_this, value,
2095 DIR_LEFT);
2096 break;
2097
2098 case PROP_ID_BORDER_STYLE:
2099 status = set_prop_border_style_from_value (a_this, value) ;
2100 break ;
2101
2102 case PROP_ID_BORDER_TOP_COLOR:
2103 status = set_prop_border_x_color_from_value (a_this, value,
2104 DIR_TOP);
2105 break;
2106
2107 case PROP_ID_BORDER_RIGHT_COLOR:
2108 status = set_prop_border_x_color_from_value (a_this, value,
2109 DIR_RIGHT);
2110 break;
2111
2112 case PROP_ID_BORDER_BOTTOM_COLOR:
2113 status = set_prop_border_x_color_from_value (a_this, value,
2114 DIR_BOTTOM);
2115 break;
2116
2117 case PROP_ID_BORDER_LEFT_COLOR:
2118 status = set_prop_border_x_color_from_value (a_this, value,
2119 DIR_BOTTOM);
2120 break;
2121
2122 case PROP_ID_BORDER_TOP:
2123 status = set_prop_border_x_from_value (a_this, value,
2124 DIR_TOP);
2125 break;
2126
2127 case PROP_ID_BORDER_RIGHT:
2128 status = set_prop_border_x_from_value (a_this, value,
2129 DIR_RIGHT);
2130 break;
2131
2132 case PROP_ID_BORDER_BOTTOM:
2133 status = set_prop_border_x_from_value (a_this, value,
2134 DIR_BOTTOM);
2135 break;
2136
2137 case PROP_ID_BORDER_LEFT:
2138 status = set_prop_border_x_from_value (a_this, value,
2139 DIR_LEFT);
2140 break;
2141
2142 case PROP_ID_MARGIN_TOP:
2143 status = set_prop_margin_x_from_value (a_this, value,
2144 DIR_TOP);
2145 break;
2146
2147 case PROP_ID_BORDER:
2148 status = set_prop_border_from_value (a_this, value);
2149 break;
2150
2151 case PROP_ID_MARGIN_RIGHT:
2152 status = set_prop_margin_x_from_value (a_this, value,
2153 DIR_RIGHT);
2154 break;
2155
2156 case PROP_ID_MARGIN_BOTTOM:
2157 status = set_prop_margin_x_from_value (a_this, value,
2158 DIR_BOTTOM);
2159 break;
2160
2161 case PROP_ID_MARGIN_LEFT:
2162 status = set_prop_margin_x_from_value (a_this, value,
2163 DIR_LEFT);
2164 break;
2165
2166 case PROP_ID_MARGIN:
2167 status = set_prop_margin_from_value (a_this, value);
2168 break;
2169
2170 case PROP_ID_DISPLAY:
2171 status = set_prop_display_from_value (a_this, value);
2172 break;
2173
2174 case PROP_ID_POSITION:
2175 status = set_prop_position_from_value (a_this, value);
2176 break;
2177
2178 case PROP_ID_TOP:
2179 status = set_prop_x_from_value (a_this, value, DIR_TOP);
2180 break;
2181
2182 case PROP_ID_RIGHT:
2183 status = set_prop_x_from_value (a_this, value, DIR_RIGHT);
2184 break;
2185
2186 case PROP_ID_BOTTOM:
2187 status = set_prop_x_from_value (a_this, value, DIR_BOTTOM);
2188 break;
2189
2190 case PROP_ID_LEFT:
2191 status = set_prop_x_from_value (a_this, value, DIR_LEFT);
2192 break;
2193
2194 case PROP_ID_FLOAT:
2195 status = set_prop_float (a_this, value);
2196 break;
2197
2198 case PROP_ID_WIDTH:
2199 status = set_prop_width (a_this, value);
2200 break;
2201
2202 case PROP_ID_COLOR:
2203 status = set_prop_color (a_this, value);
2204 break;
2205
2206 case PROP_ID_BACKGROUND_COLOR:
2207 status = set_prop_background_color (a_this, value);
2208 break;
2209
2210 case PROP_ID_FONT_FAMILY:
2211 status = set_prop_font_family_from_value (a_this, value);
2212 break;
2213
2214 case PROP_ID_FONT_SIZE:
2215 status = set_prop_font_size_from_value (a_this, value);
2216 break;
2217
2218 case PROP_ID_FONT_STYLE:
2219 status = set_prop_font_style_from_value (a_this, value);
2220 break;
2221
2222 case PROP_ID_FONT_WEIGHT:
2223 status = set_prop_font_weight_from_value (a_this, value);
2224 break;
2225
2226 case PROP_ID_WHITE_SPACE:
2227 status = set_prop_white_space_from_value(a_this, value);
2228 break;
2229
2230 default:
2231 return CR_UNKNOWN_TYPE_ERROR;
2232
2233 }
2234
2235 return status;
2236 }
2237
2238 /**
2239 *Increases the reference count
2240 *of the current instance of #CRStyle.
2241 *@param a_this the current instance of #CRStyle.
2242 *@return CR_OK upon successfull completion, an error code
2243 *otherwise.
2244 */
2245 enum CRStatus
cr_style_ref(CRStyle * a_this)2246 cr_style_ref (CRStyle * a_this)
2247 {
2248 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
2249
2250 a_this->ref_count++;
2251 return CR_OK;
2252 }
2253
2254 /**
2255 *Decreases the reference count of
2256 *the current instance of #CRStyle.
2257 *If the reference count reaches 0, the
2258 *instance of #CRStyle is destoyed.
2259 *@param a_this the current instance of #CRStyle.
2260 *@return TRUE if the instance has been destroyed, FALSE
2261 *otherwise.
2262 */
2263 gboolean
cr_style_unref(CRStyle * a_this)2264 cr_style_unref (CRStyle * a_this)
2265 {
2266 g_return_val_if_fail (a_this, FALSE);
2267
2268 if (a_this->ref_count)
2269 a_this->ref_count--;
2270
2271 if (!a_this->ref_count) {
2272 cr_style_destroy (a_this);
2273 return TRUE;
2274 }
2275
2276 return FALSE;
2277 }
2278
2279 /**
2280 *Duplicates the current instance of #CRStyle .
2281 *The newly created instance of #CRStyle must be
2282 *freed using cr_style_destroy ().
2283 *@param a_this the current instance of #CRStyle.
2284 *@return the newly duplicated instance of #CRStyle.
2285 */
2286 CRStyle *
cr_style_dup(CRStyle * a_this)2287 cr_style_dup (CRStyle * a_this)
2288 {
2289 CRStyle *result = NULL;
2290
2291 g_return_val_if_fail (a_this, NULL);
2292
2293 result = cr_style_new (FALSE);
2294 if (!result) {
2295 cr_utils_trace_info ("Out of memory");
2296 return NULL;
2297 }
2298 cr_style_copy (result, a_this);
2299 return result;
2300 }
2301
2302 /**
2303 *Copies a style data structure into another.
2304 *TODO: this is actually broken because it's based
2305 *on memcpy although some data stuctures of CRStyle should
2306 *be properly duplicated.
2307 *@param a_dest the destination style datastructure
2308 *@param a_src the source style datastructure.
2309 *@return CR_OK upon succesfull completion, an error code otherwise
2310 */
2311 enum CRStatus
cr_style_copy(CRStyle * a_dest,CRStyle * a_src)2312 cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
2313 {
2314 g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
2315
2316 memcpy (a_dest, a_src, sizeof (CRStyle));
2317 return CR_OK;
2318 }
2319
2320 /**
2321 *dump a CRNumpPropVal in a string.
2322 *@param a_prop_val the numerical property value to dump
2323 *@param a_str the string to dump the numerical propertie into.
2324 *Note that the string value is appended to a_str.
2325 *@param a_nb_indent the number white chars of indentation.
2326 */
2327 enum CRStatus
cr_style_num_prop_val_to_string(CRNumPropVal * a_prop_val,GString * a_str,guint a_nb_indent)2328 cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
2329 GString * a_str, guint a_nb_indent)
2330 {
2331 enum CRStatus status = CR_OK;
2332 guchar *tmp_str = NULL;
2333 GString *str = NULL;
2334
2335 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2336
2337 str = g_string_new (NULL);
2338 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2339 g_string_append (str, "NumPropVal {");
2340 tmp_str = cr_num_to_string (&a_prop_val->sv);
2341 if (!tmp_str) {
2342 status = CR_ERROR;
2343 goto cleanup;
2344 }
2345 g_string_append_printf (str, "sv: %s ", tmp_str);
2346 g_free (tmp_str);
2347 tmp_str = NULL;
2348
2349 tmp_str = cr_num_to_string (&a_prop_val->cv);
2350 if (!tmp_str) {
2351 status = CR_ERROR;
2352 goto cleanup;
2353 }
2354 g_string_append_printf (str, "cv: %s ", tmp_str);
2355 g_free (tmp_str);
2356 tmp_str = NULL;
2357
2358 tmp_str = cr_num_to_string (&a_prop_val->av);
2359 if (!tmp_str) {
2360 status = CR_ERROR;
2361 goto cleanup;
2362 }
2363 g_string_append_printf (str, "av: %s ", tmp_str);
2364 g_free (tmp_str);
2365 tmp_str = NULL;
2366 g_string_append (str, "}");
2367 g_string_append (a_str, str->str);
2368 status = CR_OK;
2369 cleanup:
2370
2371 if (tmp_str) {
2372 g_free (tmp_str);
2373 tmp_str = NULL;
2374 }
2375 if (str) {
2376 g_string_free (str, TRUE);
2377 }
2378 return status;
2379 }
2380
2381 enum CRStatus
cr_style_rgb_prop_val_to_string(CRRgbPropVal * a_prop_val,GString * a_str,guint a_nb_indent)2382 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
2383 GString * a_str, guint a_nb_indent)
2384 {
2385 enum CRStatus status = CR_OK;
2386 guchar *tmp_str = NULL;
2387 GString *str = NULL;
2388
2389 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
2390
2391 str = g_string_new (NULL);
2392
2393 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2394 g_string_append (str, "RGBPropVal {");
2395 tmp_str = cr_rgb_to_string (&a_prop_val->sv);
2396 if (!tmp_str) {
2397 status = CR_ERROR;
2398 goto cleanup;
2399 }
2400 g_string_append_printf (str, "sv: %s ", tmp_str);
2401 g_free (tmp_str);
2402 tmp_str = NULL;
2403 tmp_str = cr_rgb_to_string (&a_prop_val->cv);
2404 if (!tmp_str) {
2405 status = CR_ERROR;
2406 goto cleanup;
2407 }
2408 g_string_append_printf (str, "cv: %s ", tmp_str);
2409 g_free (tmp_str);
2410 tmp_str = NULL;
2411 tmp_str = cr_rgb_to_string (&a_prop_val->av);
2412 if (!tmp_str) {
2413 status = CR_ERROR;
2414 goto cleanup;
2415 }
2416 g_string_append_printf (str, "av: %s ", tmp_str);
2417 g_free (tmp_str);
2418 tmp_str = NULL;
2419
2420 g_string_append (str, "}");
2421 g_string_append (a_str, str->str);
2422 status = CR_OK;
2423 cleanup:
2424
2425 if (tmp_str) {
2426 g_free (tmp_str);
2427 tmp_str = NULL;
2428 }
2429 if (str) {
2430 g_string_free (str, TRUE);
2431 }
2432 return status;
2433 }
2434
2435 enum CRStatus
cr_style_border_style_to_string(enum CRBorderStyle a_prop,GString * a_str,guint a_nb_indent)2436 cr_style_border_style_to_string (enum CRBorderStyle a_prop,
2437 GString * a_str, guint a_nb_indent)
2438 {
2439 gchar *str = NULL;
2440
2441 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2442
2443 switch (a_prop) {
2444 case BORDER_STYLE_NONE:
2445 str = (gchar *) "border-style-none";
2446 break;
2447 case BORDER_STYLE_HIDDEN:
2448 str = (gchar *) "border-style-hidden";
2449 break;
2450 case BORDER_STYLE_DOTTED:
2451 str = (gchar *) "border-style-dotted";
2452 break;
2453 case BORDER_STYLE_DASHED:
2454 str = (gchar *) "border-style-dashed";
2455 break;
2456 case BORDER_STYLE_SOLID:
2457 str = (gchar *) "border-style-solid";
2458 break;
2459 case BORDER_STYLE_DOUBLE:
2460 str = (gchar *) "border-style-double";
2461 break;
2462 case BORDER_STYLE_GROOVE:
2463 str = (gchar *) "border-style-groove";
2464 break;
2465 case BORDER_STYLE_RIDGE:
2466 str = (gchar *) "border-style-ridge";
2467 break;
2468 case BORDER_STYLE_INSET:
2469 str = (gchar *) "border-style-inset";
2470 break;
2471 case BORDER_STYLE_OUTSET:
2472 str = (gchar *) "border-style-outset";
2473 break;
2474 default:
2475 str = (gchar *) "unknown border style";
2476 break;
2477 }
2478 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2479 g_string_append (a_str, str);
2480 return CR_OK;
2481 }
2482
2483 enum CRStatus
cr_style_display_type_to_string(enum CRDisplayType a_code,GString * a_str,guint a_nb_indent)2484 cr_style_display_type_to_string (enum CRDisplayType a_code,
2485 GString * a_str, guint a_nb_indent)
2486 {
2487 gchar *str = NULL;
2488
2489 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2490
2491 switch (a_code) {
2492 case DISPLAY_NONE:
2493 str = (gchar *) "display-none";
2494 break;
2495 case DISPLAY_INLINE:
2496 str = (gchar *) "display-inline";
2497 break;
2498 case DISPLAY_BLOCK:
2499 str = (gchar *) "display-block";
2500 break;
2501 case DISPLAY_LIST_ITEM:
2502 str = (gchar *) "display-list-item";
2503 break;
2504 case DISPLAY_RUN_IN:
2505 str = (gchar *) "display-run-in";
2506 break;
2507 case DISPLAY_COMPACT:
2508 str = (gchar *) "display-compact";
2509 break;
2510 case DISPLAY_MARKER:
2511 str = (gchar *) "display-marker";
2512 break;
2513 case DISPLAY_TABLE:
2514 str = (gchar *) "display-table";
2515 break;
2516 case DISPLAY_INLINE_TABLE:
2517 str = (gchar *) "display-inline-table";
2518 break;
2519 case DISPLAY_TABLE_ROW_GROUP:
2520 str = (gchar *) "display-table-row-group";
2521 break;
2522 case DISPLAY_TABLE_HEADER_GROUP:
2523 str = (gchar *) "display-table-header-group";
2524 break;
2525 case DISPLAY_TABLE_FOOTER_GROUP:
2526 str = (gchar *) "display-table-footer-group";
2527 break;
2528 case DISPLAY_TABLE_ROW:
2529 str = (gchar *) "display-table-row";
2530 break;
2531 case DISPLAY_TABLE_COLUMN_GROUP:
2532 str = (gchar *) "display-table-column-group";
2533 break;
2534 case DISPLAY_TABLE_COLUMN:
2535 str = (gchar *) "display-table-column";
2536 break;
2537 case DISPLAY_TABLE_CELL:
2538 str = (gchar *) "display-table-cell";
2539 break;
2540 case DISPLAY_TABLE_CAPTION:
2541 str = (gchar *) "display-table-caption";
2542 break;
2543 case DISPLAY_INHERIT:
2544 str = (gchar *) "display-inherit";
2545 break;
2546 default:
2547 str = (gchar *) "unknown display property";
2548 break;
2549 }
2550 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2551 g_string_append (a_str, str);
2552 return CR_OK;
2553
2554 }
2555
2556 enum CRStatus
cr_style_position_type_to_string(enum CRPositionType a_code,GString * a_str,guint a_nb_indent)2557 cr_style_position_type_to_string (enum CRPositionType a_code,
2558 GString * a_str, guint a_nb_indent)
2559 {
2560 gchar *str = NULL;
2561
2562 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2563
2564 switch (a_code) {
2565 case POSITION_STATIC:
2566 str = (gchar *) "position-static";
2567 break;
2568 case POSITION_RELATIVE:
2569 str = (gchar *) "position-relative";
2570 break;
2571 case POSITION_ABSOLUTE:
2572 str = (gchar *) "position-absolute";
2573 break;
2574 case POSITION_FIXED:
2575 str = (gchar *) "position-fixed";
2576 break;
2577 case POSITION_INHERIT:
2578 str = (gchar *) "position-inherit";
2579 break;
2580 default:
2581 str = (gchar *) "unknown static property";
2582 }
2583 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2584 g_string_append (a_str, str);
2585 return CR_OK;
2586 }
2587
2588 enum CRStatus
cr_style_float_type_to_string(enum CRFloatType a_code,GString * a_str,guint a_nb_indent)2589 cr_style_float_type_to_string (enum CRFloatType a_code,
2590 GString * a_str, guint a_nb_indent)
2591 {
2592 gchar *str = NULL;
2593
2594 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2595
2596 switch (a_code) {
2597 case FLOAT_NONE:
2598 str = (gchar *) "float-none";
2599 break;
2600 case FLOAT_LEFT:
2601 str = (gchar *) "float-left";
2602 break;
2603 case FLOAT_RIGHT:
2604 str = (gchar *) "float-right";
2605 break;
2606 case FLOAT_INHERIT:
2607 str = (gchar *) "float-inherit";
2608 break;
2609 default:
2610 str = (gchar *) "unknown float property value";
2611 break;
2612 }
2613 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2614 g_string_append (a_str, str);
2615 return CR_OK;
2616 }
2617
2618 enum CRStatus
cr_style_white_space_type_to_string(enum CRWhiteSpaceType a_code,GString * a_str,guint a_nb_indent)2619 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
2620 GString * a_str, guint a_nb_indent)
2621 {
2622 gchar *str = NULL;
2623
2624 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
2625
2626 switch (a_code) {
2627 case WHITE_SPACE_NORMAL:
2628 str = (gchar *) "normal";
2629 break;
2630 case WHITE_SPACE_PRE:
2631 str = (gchar *) "pre";
2632 break;
2633 case WHITE_SPACE_NOWRAP:
2634 str = (gchar *) "nowrap";
2635 break;
2636 case WHITE_SPACE_INHERIT:
2637 str = (gchar *) "inherited";
2638 break;
2639 default:
2640 str = (gchar *) "unknow white space property value";
2641 break;
2642 }
2643 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
2644 g_string_append (a_str, str);
2645 return CR_OK;
2646 }
2647
2648 /**
2649 *Serializes in instance of #CRStyle into
2650 *a string
2651 *@param a_this the instance of #CRStyle to serialize
2652 *@param a_str the string to serialise the style into.
2653 *if *a_str is NULL, a new GString is instanciated, otherwise
2654 *the style serialisation is appended to the existed *a_str
2655 *@param the number of white space char to use for indentation.
2656 *@return CR_OK upon successful completion, an error code otherwise.
2657 */
2658 enum CRStatus
cr_style_to_string(CRStyle * a_this,GString ** a_str,guint a_nb_indent)2659 cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
2660 {
2661 const gint INTERNAL_INDENT = 2;
2662 gint indent = a_nb_indent + INTERNAL_INDENT;
2663 gchar *tmp_str = NULL;
2664 GString *str = NULL;
2665 gint i = 0;
2666
2667 g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
2668
2669 if (!*a_str) {
2670 str = g_string_new (NULL);
2671 } else {
2672 str = *a_str;
2673 }
2674 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2675 g_string_append (str, "style {\n");
2676
2677 /*loop over the num_props and to_string() them */
2678 for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
2679 /*
2680 *to_string() the name of the num_prop
2681 *(using num_prop_code_to_string)
2682 *before outputing it value
2683 */
2684 cr_utils_dump_n_chars2 (' ', str, indent);
2685 tmp_str = (gchar *) num_prop_code_to_string (i);
2686 if (tmp_str) {
2687 g_string_append_printf (str, "%s: ", tmp_str);
2688 } else {
2689 g_string_append (str, "NULL");
2690 }
2691 tmp_str = NULL;
2692 cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
2693 a_nb_indent +
2694 INTERNAL_INDENT);
2695 g_string_append (str, "\n");
2696 }
2697 /*loop over the rgb_props and to_string() them all */
2698 for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
2699 tmp_str = (gchar *) rgb_prop_code_to_string (i);
2700 cr_utils_dump_n_chars2 (' ', str, indent);
2701 if (tmp_str) {
2702 g_string_append_printf (str, "%s: ", tmp_str);
2703 } else {
2704 g_string_append (str, "NULL: ");
2705 }
2706 tmp_str = NULL;
2707 cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
2708 a_nb_indent +
2709 INTERNAL_INDENT);
2710 g_string_append (str, "\n");
2711 }
2712 /*loop over the border_style_props and to_string() them */
2713 for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
2714 tmp_str = (gchar *) border_style_prop_code_to_string (i);
2715 cr_utils_dump_n_chars2 (' ', str, indent);
2716 if (tmp_str) {
2717 g_string_append_printf (str, "%s: ", tmp_str);
2718 } else {
2719 g_string_append (str, "NULL: ");
2720 }
2721 tmp_str = NULL;
2722 cr_style_border_style_to_string (a_this->
2723 border_style_props[i], str,
2724 0);
2725 g_string_append (str, "\n");
2726 }
2727 cr_utils_dump_n_chars2 (' ', str, indent);
2728 g_string_append (str, "display: ");
2729 cr_style_display_type_to_string (a_this->display, str, 0);
2730 g_string_append (str, "\n");
2731
2732 cr_utils_dump_n_chars2 (' ', str, indent);
2733 g_string_append (str, "position: ");
2734 cr_style_position_type_to_string (a_this->position, str, 0);
2735 g_string_append (str, "\n");
2736
2737 cr_utils_dump_n_chars2 (' ', str, indent);
2738 g_string_append (str, "float-type: ");
2739 cr_style_float_type_to_string (a_this->float_type, str, 0);
2740 g_string_append (str, "\n");
2741
2742 cr_utils_dump_n_chars2 (' ', str, indent);
2743 g_string_append (str, "white-space: ");
2744 cr_style_white_space_type_to_string (a_this->white_space, str, 0);
2745 g_string_append (str, "\n");
2746
2747 cr_utils_dump_n_chars2 (' ', str, indent);
2748 g_string_append (str, "font-family: ");
2749 tmp_str = cr_font_family_to_string (a_this->font_family, TRUE);
2750 if (tmp_str) {
2751 g_string_append (str, tmp_str);
2752 g_free (tmp_str);
2753 tmp_str = NULL;
2754 } else {
2755 g_string_append (str, "NULL");
2756 }
2757 g_string_append (str, "\n");
2758
2759 cr_utils_dump_n_chars2 (' ', str, indent);
2760 tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
2761 if (tmp_str) {
2762 g_string_append_printf (str, "font-size {sv:%s, ",
2763 tmp_str) ;
2764 } else {
2765 g_string_append (str, "font-size {sv:NULL, ");
2766 }
2767 tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
2768 if (tmp_str) {
2769 g_string_append_printf (str, "cv:%s, ", tmp_str);
2770 } else {
2771 g_string_append (str, "cv:NULL, ");
2772 }
2773 tmp_str = cr_font_size_to_string (&a_this->font_size.av);
2774 if (tmp_str) {
2775 g_string_append_printf (str, "av:%s}", tmp_str);
2776 } else {
2777 g_string_append (str, "av:NULL}");
2778 }
2779
2780 tmp_str = NULL;
2781 g_string_append (str, "\n");
2782
2783 cr_utils_dump_n_chars2 (' ', str, indent);
2784 tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
2785 if (tmp_str) {
2786 g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
2787 } else {
2788 g_string_append (str, "font-size-adjust: NULL");
2789 }
2790 tmp_str = NULL;
2791 g_string_append (str, "\n");
2792
2793 cr_utils_dump_n_chars2 (' ', str, indent);
2794 tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
2795 if (tmp_str) {
2796 g_string_append_printf (str, "font-style: %s", tmp_str);
2797 } else {
2798 g_string_append (str, "font-style: NULL");
2799 }
2800 tmp_str = NULL;
2801 g_string_append (str, "\n");
2802
2803 cr_utils_dump_n_chars2 (' ', str, indent);
2804 tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
2805 if (tmp_str) {
2806 g_string_append_printf (str, "font-variant: %s", tmp_str);
2807 } else {
2808 g_string_append (str, "font-variant: NULL");
2809 }
2810 tmp_str = NULL;
2811 g_string_append (str, "\n");
2812
2813 cr_utils_dump_n_chars2 (' ', str, indent);
2814 tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
2815 if (tmp_str) {
2816 g_string_append_printf (str, "font-weight: %s", tmp_str);
2817 } else {
2818 g_string_append (str, "font-weight: NULL");
2819 }
2820 tmp_str = NULL;
2821 g_string_append (str, "\n");
2822
2823 cr_utils_dump_n_chars2 (' ', str, indent);
2824 tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
2825 if (tmp_str) {
2826 g_string_append_printf (str, "font-stretch: %s", tmp_str);
2827 } else {
2828 g_string_append (str, "font-stretch: NULL");
2829 }
2830 tmp_str = NULL;
2831 g_string_append (str, "\n");
2832
2833
2834 cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
2835 g_string_append (str, "}");
2836
2837 return CR_OK;
2838 }
2839
2840 /**
2841 *Destructor of the #CRStyle class.
2842 *@param a_this the instance to destroy.
2843 */
2844 void
cr_style_destroy(CRStyle * a_this)2845 cr_style_destroy (CRStyle * a_this)
2846 {
2847 g_return_if_fail (a_this);
2848
2849 g_free (a_this);
2850 }
2851
2852