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