Libcroco
|
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ 00002 00003 /* 00004 * This file is part of The Croco Library 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of version 2.1 of 00008 * the GNU Lesser General Public 00009 * License as published by the Free Software Foundation. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the 00017 * GNU Lesser General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00020 * USA 00021 * 00022 * Author: Dodji Seketeli. 00023 * see COPYRIGTHS file for copyright information 00024 */ 00025 00026 #include <string.h> 00027 #include "cr-style.h" 00028 00029 /** 00030 *@file 00031 *The definition of the #CRStyle class. 00032 */ 00033 00034 /** 00035 *A property ID. 00036 *Each supported css property has an ID which is 00037 *an entry into a property "population" jump table. 00038 *each entry of the property population jump table 00039 *contains code to tranform the literal form of 00040 *a property value into a strongly typed value. 00041 */ 00042 enum CRPropertyID { 00043 PROP_ID_NOT_KNOWN = 0, 00044 PROP_ID_PADDING_TOP, 00045 PROP_ID_PADDING_RIGHT, 00046 PROP_ID_PADDING_BOTTOM, 00047 PROP_ID_PADDING_LEFT, 00048 PROP_ID_PADDING, 00049 PROP_ID_BORDER_TOP_WIDTH, 00050 PROP_ID_BORDER_RIGHT_WIDTH, 00051 PROP_ID_BORDER_BOTTOM_WIDTH, 00052 PROP_ID_BORDER_LEFT_WIDTH, 00053 PROP_ID_BORDER_WIDTH, 00054 PROP_ID_BORDER_TOP_STYLE, 00055 PROP_ID_BORDER_RIGHT_STYLE, 00056 PROP_ID_BORDER_BOTTOM_STYLE, 00057 PROP_ID_BORDER_LEFT_STYLE, 00058 PROP_ID_BORDER_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 PROP_ID_WHITE_SPACE, 00088 /*should be the last one. */ 00089 NB_PROP_IDS 00090 }; 00091 00092 typedef struct _CRPropertyDesc CRPropertyDesc; 00093 00094 struct _CRPropertyDesc { 00095 const gchar *name; 00096 enum CRPropertyID prop_id; 00097 }; 00098 00099 static CRPropertyDesc gv_prop_table[] = { 00100 {"padding-top", PROP_ID_PADDING_TOP}, 00101 {"padding-right", PROP_ID_PADDING_RIGHT}, 00102 {"padding-bottom", PROP_ID_PADDING_BOTTOM}, 00103 {"padding-left", PROP_ID_PADDING_LEFT}, 00104 {"padding", PROP_ID_PADDING}, 00105 {"border-top-width", PROP_ID_BORDER_TOP_WIDTH}, 00106 {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH}, 00107 {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH}, 00108 {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH}, 00109 {"border-width", PROP_ID_BORDER_WIDTH}, 00110 {"border-top-style", PROP_ID_BORDER_TOP_STYLE}, 00111 {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE}, 00112 {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE}, 00113 {"border-left-style", PROP_ID_BORDER_LEFT_STYLE}, 00114 {"border-style", PROP_ID_BORDER_STYLE}, 00115 {"border-top", PROP_ID_BORDER_TOP}, 00116 {"border-right", PROP_ID_BORDER_RIGHT}, 00117 {"border-bottom", PROP_ID_BORDER_BOTTOM}, 00118 {"border-left", PROP_ID_BORDER_LEFT}, 00119 {"border", PROP_ID_BORDER}, 00120 {"margin-top", PROP_ID_MARGIN_TOP}, 00121 {"margin-right", PROP_ID_MARGIN_RIGHT}, 00122 {"margin-bottom", PROP_ID_MARGIN_BOTTOM}, 00123 {"margin-left", PROP_ID_MARGIN_LEFT}, 00124 {"margin", PROP_ID_MARGIN}, 00125 {"display", PROP_ID_DISPLAY}, 00126 {"position", PROP_ID_POSITION}, 00127 {"top", PROP_ID_TOP}, 00128 {"right", PROP_ID_RIGHT}, 00129 {"bottom", PROP_ID_BOTTOM}, 00130 {"left", PROP_ID_LEFT}, 00131 {"float", PROP_ID_FLOAT}, 00132 {"width", PROP_ID_WIDTH}, 00133 {"color", PROP_ID_COLOR}, 00134 {"border-top-color", PROP_ID_BORDER_TOP_COLOR}, 00135 {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR}, 00136 {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR}, 00137 {"border-left-color", PROP_ID_BORDER_LEFT_COLOR}, 00138 {"background-color", PROP_ID_BACKGROUND_COLOR}, 00139 {"font-family", PROP_ID_FONT_FAMILY}, 00140 {"font-size", PROP_ID_FONT_SIZE}, 00141 {"font-style", PROP_ID_FONT_STYLE}, 00142 {"font-weight", PROP_ID_FONT_WEIGHT}, 00143 {"white-space", PROP_ID_WHITE_SPACE}, 00144 /*must be the last one */ 00145 {NULL, 0} 00146 }; 00147 00148 /** 00149 *A the key/value pair of this hash table 00150 *are: 00151 *key => name of the the css propertie found in gv_prop_table 00152 *value => matching property id found in gv_prop_table. 00153 *So this hash table is here just to retrieval of a property id 00154 *from a property name. 00155 */ 00156 static GHashTable *gv_prop_hash = NULL; 00157 00158 /** 00159 *incremented by each new instance of #CRStyle 00160 *and decremented at the it destroy time. 00161 *When this reaches zero, gv_prop_hash is destroyed. 00162 */ 00163 static gulong gv_prop_hash_ref_count = 0; 00164 00165 struct CRNumPropEnumDumpInfo { 00166 enum CRNumProp code; 00167 const gchar *str; 00168 }; 00169 00170 static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = { 00171 {NUM_PROP_TOP, "top"}, 00172 {NUM_PROP_RIGHT, "right"}, 00173 {NUM_PROP_BOTTOM, "bottom"}, 00174 {NUM_PROP_LEFT, "left"}, 00175 {NUM_PROP_PADDING_TOP, "padding-top"}, 00176 {NUM_PROP_PADDING_RIGHT, "padding-right"}, 00177 {NUM_PROP_PADDING_BOTTOM, "padding-bottom"}, 00178 {NUM_PROP_PADDING_LEFT, "padding-left"}, 00179 {NUM_PROP_BORDER_TOP, "border-top"}, 00180 {NUM_PROP_BORDER_RIGHT, "border-right"}, 00181 {NUM_PROP_BORDER_BOTTOM, "border-bottom"}, 00182 {NUM_PROP_BORDER_LEFT, "border-left"}, 00183 {NUM_PROP_MARGIN_TOP, "margin-top"}, 00184 {NUM_PROP_MARGIN_RIGHT, "margin-right"}, 00185 {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"}, 00186 {NUM_PROP_MARGIN_LEFT, "margin-left"}, 00187 {NUM_PROP_WIDTH, "width"}, 00188 {0, NULL} 00189 }; 00190 00191 struct CRRgbPropEnumDumpInfo { 00192 enum CRRgbProp code; 00193 const gchar *str; 00194 }; 00195 00196 static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = { 00197 {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"}, 00198 {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"}, 00199 {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"}, 00200 {RGB_PROP_BORDER_LEFT_COLOR, "left-color"}, 00201 {RGB_PROP_COLOR, "color"}, 00202 {RGB_PROP_BACKGROUND_COLOR, "background-color"}, 00203 {0, NULL} 00204 }; 00205 00206 struct CRBorderStylePropEnumDumpInfo { 00207 enum CRBorderStyleProp code; 00208 const gchar *str; 00209 00210 }; 00211 00212 static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[] 00213 = { 00214 {BORDER_STYLE_PROP_TOP, "border-style-top"}, 00215 {BORDER_STYLE_PROP_RIGHT, "border-style-right"}, 00216 {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"}, 00217 {BORDER_STYLE_PROP_LEFT, "border-style-left"}, 00218 {0, NULL} 00219 }; 00220 00221 static enum CRStatus 00222 cr_style_init_properties (void); 00223 00224 enum CRDirection { 00225 DIR_TOP = 0, 00226 DIR_RIGHT, 00227 DIR_BOTTOM, 00228 DIR_LEFT, 00229 00230 /*must be the last one */ 00231 NB_DIRS 00232 }; 00233 00234 static const gchar *num_prop_code_to_string (enum CRNumProp a_code); 00235 00236 static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code); 00237 00238 static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp 00239 a_code); 00240 00241 static enum CRStatus 00242 set_prop_padding_x_from_value (CRStyle * a_style, 00243 CRTerm * a_value, enum CRDirection a_dir); 00244 00245 static enum CRStatus 00246 set_prop_border_x_width_from_value (CRStyle * a_style, 00247 CRTerm * a_value, 00248 enum CRDirection a_dir); 00249 static enum CRStatus 00250 set_prop_border_width_from_value (CRStyle *a_style, 00251 CRTerm *a_value) ; 00252 00253 static enum CRStatus 00254 set_prop_border_x_style_from_value (CRStyle * a_style, 00255 CRTerm * a_value, 00256 enum CRDirection a_dir); 00257 static enum CRStatus 00258 set_prop_border_style_from_value (CRStyle *a_style, 00259 CRTerm *a_value) ; 00260 00261 static enum CRStatus 00262 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, 00263 enum CRDirection a_dir); 00264 00265 static enum CRStatus 00266 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value); 00267 00268 static enum CRStatus 00269 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value); 00270 00271 static enum CRStatus 00272 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, 00273 enum CRDirection a_dir); 00274 00275 static enum CRStatus 00276 set_prop_float (CRStyle * a_style, CRTerm * a_value); 00277 00278 static enum CRStatus 00279 set_prop_width (CRStyle * a_style, CRTerm * a_value); 00280 00281 static enum CRStatus 00282 set_prop_color (CRStyle * a_style, CRTerm * a_value); 00283 00284 static enum CRStatus 00285 set_prop_background_color (CRStyle * a_style, CRTerm * a_value); 00286 00287 static enum CRStatus 00288 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, 00289 enum CRDirection a_dir); 00290 00291 static enum CRStatus 00292 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, 00293 enum CRDirection a_dir); 00294 00295 static enum CRStatus 00296 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value); 00297 00298 static enum CRStatus 00299 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value); 00300 00301 static enum CRStatus 00302 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value); 00303 00304 static enum CRStatus 00305 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value); 00306 00307 static enum CRStatus 00308 init_style_font_size_field (CRStyle * a_style); 00309 00310 static enum CRStatus 00311 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value); 00312 00313 static enum CRStatus 00314 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value); 00315 00316 static enum CRStatus 00317 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value); 00318 00319 static const gchar * 00320 num_prop_code_to_string (enum CRNumProp a_code) 00321 { 00322 guint len = sizeof (gv_num_props_dump_infos) / 00323 sizeof (struct CRNumPropEnumDumpInfo); 00324 if (a_code >= len) { 00325 cr_utils_trace_info ("A field has been added " 00326 "to 'enum CRNumProp' and no matching" 00327 " entry has been " 00328 "added to gv_num_prop_dump_infos table.\n" 00329 "Please add the missing matching entry"); 00330 return NULL; 00331 } 00332 if (gv_num_props_dump_infos[a_code].code != a_code) { 00333 cr_utils_trace_info ("mismatch between the order of fields in" 00334 " 'enum CRNumProp' and " 00335 "the order of entries in " 00336 "the gv_num_prop_dump_infos table"); 00337 return NULL; 00338 } 00339 return gv_num_props_dump_infos[a_code].str; 00340 } 00341 00342 static const gchar * 00343 rgb_prop_code_to_string (enum CRRgbProp a_code) 00344 { 00345 guint len = sizeof (gv_rgb_props_dump_infos) / 00346 sizeof (struct CRRgbPropEnumDumpInfo); 00347 00348 if (a_code >= len) { 00349 cr_utils_trace_info ("A field has been added " 00350 "to 'enum CRRgbProp' and no matching" 00351 " entry has been " 00352 "added to gv_rgb_prop_dump_infos table.\n" 00353 "Please add the missing matching entry"); 00354 return NULL; 00355 } 00356 if (gv_rgb_props_dump_infos[a_code].code != a_code) { 00357 cr_utils_trace_info ("mismatch between the order of fields in" 00358 " 'enum CRRgbProp' and " 00359 "the order of entries in " 00360 "the gv_rgb_props_dump_infos table"); 00361 return NULL; 00362 } 00363 return gv_rgb_props_dump_infos[a_code].str; 00364 } 00365 00366 static const gchar * 00367 border_style_prop_code_to_string (enum CRBorderStyleProp a_code) 00368 { 00369 guint len = sizeof (gv_border_style_props_dump_infos) / 00370 sizeof (struct CRBorderStylePropEnumDumpInfo); 00371 00372 if (a_code >= len) { 00373 cr_utils_trace_info ("A field has been added " 00374 "to 'enum CRBorderStyleProp' and no matching" 00375 " entry has been " 00376 "added to gv_border_style_prop_dump_infos table.\n" 00377 "Please add the missing matching entry"); 00378 return NULL; 00379 } 00380 if (gv_border_style_props_dump_infos[a_code].code != a_code) { 00381 cr_utils_trace_info ("mismatch between the order of fields in" 00382 " 'enum CRBorderStyleProp' and " 00383 "the order of entries in " 00384 "the gv_border_style_props_dump_infos table"); 00385 return NULL; 00386 } 00387 return gv_border_style_props_dump_infos[a_code].str; 00388 } 00389 00390 static enum CRStatus 00391 cr_style_init_properties (void) 00392 { 00393 00394 if (!gv_prop_hash) { 00395 gulong i = 0; 00396 00397 gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal); 00398 if (!gv_prop_hash) { 00399 cr_utils_trace_info ("Out of memory"); 00400 return CR_ERROR; 00401 } 00402 00403 /*load gv_prop_hash from gv_prop_table */ 00404 for (i = 0; gv_prop_table[i].name; i++) { 00405 g_hash_table_insert 00406 (gv_prop_hash, 00407 (gpointer) gv_prop_table[i].name, 00408 GINT_TO_POINTER (gv_prop_table[i].prop_id)); 00409 } 00410 } 00411 00412 return CR_OK; 00413 } 00414 00415 static enum CRPropertyID 00416 cr_style_get_prop_id (const guchar * a_prop) 00417 { 00418 gpointer *raw_id = NULL; 00419 00420 if (!gv_prop_hash) { 00421 cr_style_init_properties (); 00422 } 00423 00424 raw_id = g_hash_table_lookup (gv_prop_hash, a_prop); 00425 if (!raw_id) { 00426 return PROP_ID_NOT_KNOWN; 00427 } 00428 return GPOINTER_TO_INT (raw_id); 00429 } 00430 00431 static enum CRStatus 00432 set_prop_padding_x_from_value (CRStyle * a_style, 00433 CRTerm * a_value, enum CRDirection a_dir) 00434 { 00435 enum CRStatus status = CR_OK; 00436 CRNum *num_val = NULL; 00437 00438 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 00439 00440 if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT) 00441 return CR_BAD_PARAM_ERROR; 00442 00443 switch (a_dir) { 00444 case DIR_TOP: 00445 num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv; 00446 break; 00447 00448 case DIR_RIGHT: 00449 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv; 00450 break; 00451 00452 case DIR_BOTTOM: 00453 num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv; 00454 break; 00455 00456 case DIR_LEFT: 00457 num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv; 00458 break; 00459 00460 default: 00461 return CR_BAD_PARAM_ERROR; 00462 } 00463 00464 if (a_value->type == TERM_IDENT) { 00465 if (a_value->content.str 00466 && a_value->content.str->stryng 00467 && a_value->content.str->stryng->str 00468 && !strncmp ((const char *) "inherit", 00469 a_value->content.str->stryng->str, 00470 sizeof ("inherit")-1)) { 00471 status = cr_num_set (num_val, 0.0, NUM_INHERIT); 00472 return CR_OK; 00473 } else 00474 return CR_UNKNOWN_TYPE_ERROR; 00475 } 00476 00477 g_return_val_if_fail (a_value->type == TERM_NUMBER 00478 && a_value->content.num, CR_UNKNOWN_TYPE_ERROR); 00479 00480 switch (a_value->content.num->type) { 00481 case NUM_LENGTH_EM: 00482 case NUM_LENGTH_EX: 00483 case NUM_LENGTH_PX: 00484 case NUM_LENGTH_IN: 00485 case NUM_LENGTH_CM: 00486 case NUM_LENGTH_MM: 00487 case NUM_LENGTH_PT: 00488 case NUM_LENGTH_PC: 00489 case NUM_PERCENTAGE: 00490 status = cr_num_copy (num_val, a_value->content.num); 00491 break; 00492 default: 00493 status = CR_UNKNOWN_TYPE_ERROR; 00494 break; 00495 } 00496 00497 return status; 00498 } 00499 00500 static enum CRStatus 00501 set_prop_border_x_width_from_value (CRStyle * a_style, 00502 CRTerm * a_value, 00503 enum CRDirection a_dir) 00504 { 00505 enum CRStatus status = CR_OK; 00506 CRNum *num_val = NULL; 00507 00508 g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR); 00509 00510 switch (a_dir) { 00511 case DIR_TOP: 00512 num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv; 00513 break; 00514 00515 case DIR_RIGHT: 00516 num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv; 00517 break; 00518 00519 case DIR_BOTTOM: 00520 num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv; 00521 break; 00522 00523 case DIR_LEFT: 00524 num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv; 00525 break; 00526 00527 default: 00528 return CR_BAD_PARAM_ERROR; 00529 break; 00530 } 00531 00532 if (a_value->type == TERM_IDENT) { 00533 if (a_value->content.str 00534 && a_value->content.str->stryng 00535 && a_value->content.str->stryng->str) { 00536 if (!strncmp ("thin", 00537 a_value->content.str->stryng->str, 00538 sizeof ("thin")-1)) { 00539 cr_num_set (num_val, BORDER_THIN, 00540 NUM_LENGTH_PX); 00541 } else if (!strncmp 00542 ("medium", 00543 a_value->content.str->stryng->str, 00544 sizeof ("medium")-1)) { 00545 cr_num_set (num_val, BORDER_MEDIUM, 00546 NUM_LENGTH_PX); 00547 } else if (!strncmp ("thick", 00548 a_value->content.str->stryng->str, 00549 sizeof ("thick")-1)) { 00550 cr_num_set (num_val, BORDER_THICK, 00551 NUM_LENGTH_PX); 00552 } else { 00553 return CR_UNKNOWN_TYPE_ERROR; 00554 } 00555 } 00556 } else if (a_value->type == TERM_NUMBER) { 00557 if (a_value->content.num) { 00558 cr_num_copy (num_val, a_value->content.num); 00559 } 00560 } else if (a_value->type != TERM_NUMBER 00561 || a_value->content.num == NULL) { 00562 return CR_UNKNOWN_TYPE_ERROR; 00563 } 00564 00565 return status; 00566 } 00567 00568 static enum CRStatus 00569 set_prop_border_width_from_value (CRStyle *a_style, 00570 CRTerm *a_value) 00571 { 00572 CRTerm *cur_term = NULL ; 00573 enum CRDirection direction = DIR_TOP ; 00574 00575 g_return_val_if_fail (a_style && a_value, 00576 CR_BAD_PARAM_ERROR) ; 00577 cur_term = a_value ; 00578 00579 if (!cur_term) 00580 return CR_ERROR ; 00581 00582 for (direction = DIR_TOP ; 00583 direction < NB_DIRS ; direction ++) { 00584 set_prop_border_x_width_from_value (a_style, 00585 cur_term, 00586 direction) ; 00587 } 00588 00589 cur_term = cur_term->next ; 00590 if (!cur_term) 00591 return CR_OK ; 00592 set_prop_border_x_width_from_value (a_style, cur_term, 00593 DIR_RIGHT) ; 00594 set_prop_border_x_width_from_value (a_style, cur_term, 00595 DIR_LEFT) ; 00596 00597 cur_term = cur_term->next ; 00598 if (!cur_term) 00599 return CR_OK ; 00600 set_prop_border_x_width_from_value (a_style, cur_term, 00601 DIR_BOTTOM) ; 00602 00603 cur_term = cur_term->next ; 00604 if (!cur_term) 00605 return CR_OK ; 00606 set_prop_border_x_width_from_value (a_style, cur_term, 00607 DIR_LEFT) ; 00608 00609 return CR_OK ; 00610 } 00611 00612 static enum CRStatus 00613 set_prop_border_x_style_from_value (CRStyle * a_style, 00614 CRTerm * a_value, enum CRDirection a_dir) 00615 { 00616 enum CRStatus status = CR_OK; 00617 enum CRBorderStyle *border_style_ptr = NULL; 00618 00619 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 00620 00621 switch (a_dir) { 00622 case DIR_TOP: 00623 border_style_ptr = &a_style-> 00624 border_style_props[BORDER_STYLE_PROP_TOP]; 00625 break; 00626 00627 case DIR_RIGHT: 00628 border_style_ptr = 00629 &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT]; 00630 break; 00631 00632 case DIR_BOTTOM: 00633 border_style_ptr = &a_style-> 00634 border_style_props[BORDER_STYLE_PROP_BOTTOM]; 00635 break; 00636 00637 case DIR_LEFT: 00638 border_style_ptr = &a_style-> 00639 border_style_props[BORDER_STYLE_PROP_LEFT]; 00640 break; 00641 00642 default: 00643 break; 00644 } 00645 00646 if (a_value->type != TERM_IDENT || !a_value->content.str) { 00647 return CR_UNKNOWN_TYPE_ERROR; 00648 } 00649 00650 if (!strncmp ("none", 00651 a_value->content.str->stryng->str, 00652 sizeof ("none")-1)) { 00653 *border_style_ptr = BORDER_STYLE_NONE; 00654 } else if (!strncmp ("hidden", 00655 a_value->content.str->stryng->str, 00656 sizeof ("hidden")-1)) { 00657 *border_style_ptr = BORDER_STYLE_HIDDEN; 00658 } else if (!strncmp ("dotted", 00659 a_value->content.str->stryng->str, 00660 sizeof ("dotted")-1)) { 00661 *border_style_ptr = BORDER_STYLE_DOTTED; 00662 } else if (!strncmp ("dashed", 00663 a_value->content.str->stryng->str, sizeof ("dashed")-1)) { 00664 *border_style_ptr = BORDER_STYLE_DASHED; 00665 } else if (!strncmp ("solid", 00666 a_value->content.str->stryng->str, sizeof ("solid")-1)) { 00667 *border_style_ptr = BORDER_STYLE_SOLID; 00668 } else if (!strncmp ("double", 00669 a_value->content.str->stryng->str, sizeof ("double")-1)) { 00670 *border_style_ptr = BORDER_STYLE_DOUBLE; 00671 } else if (!strncmp ("groove", 00672 a_value->content.str->stryng->str, sizeof ("groove")-1)) { 00673 *border_style_ptr = BORDER_STYLE_GROOVE; 00674 } else if (!strncmp ("ridge", 00675 a_value->content.str->stryng->str, 00676 sizeof ("ridge")-1)) { 00677 *border_style_ptr = BORDER_STYLE_RIDGE; 00678 } else if (!strncmp ("inset", 00679 a_value->content.str->stryng->str, 00680 sizeof ("inset")-1)) { 00681 *border_style_ptr = BORDER_STYLE_INSET; 00682 } else if (!strncmp ("outset", 00683 a_value->content.str->stryng->str, 00684 sizeof ("outset")-1)) { 00685 *border_style_ptr = BORDER_STYLE_OUTSET; 00686 } else if (!strncmp ("inherit", 00687 a_value->content.str->stryng->str, 00688 sizeof ("inherit")-1)) { 00689 *border_style_ptr = BORDER_STYLE_INHERIT; 00690 } else { 00691 status = CR_UNKNOWN_TYPE_ERROR; 00692 } 00693 00694 return status; 00695 } 00696 00697 static enum CRStatus 00698 set_prop_border_style_from_value (CRStyle *a_style, 00699 CRTerm *a_value) 00700 { 00701 CRTerm *cur_term = NULL ; 00702 enum CRDirection direction = DIR_TOP ; 00703 00704 g_return_val_if_fail (a_style && a_value, 00705 CR_BAD_PARAM_ERROR) ; 00706 00707 cur_term = a_value ; 00708 if (!cur_term || cur_term->type != TERM_IDENT) { 00709 return CR_ERROR ; 00710 } 00711 00712 for (direction = DIR_TOP ; 00713 direction < NB_DIRS ; 00714 direction ++) { 00715 set_prop_border_x_style_from_value (a_style, 00716 cur_term, 00717 direction) ; 00718 } 00719 00720 cur_term = cur_term->next ; 00721 if (!cur_term || cur_term->type != TERM_IDENT) { 00722 return CR_OK ; 00723 } 00724 00725 set_prop_border_x_style_from_value (a_style, cur_term, 00726 DIR_RIGHT) ; 00727 set_prop_border_x_style_from_value (a_style, cur_term, 00728 DIR_LEFT) ; 00729 00730 cur_term = cur_term->next ; 00731 if (!cur_term || cur_term->type != TERM_IDENT) { 00732 return CR_OK ; 00733 } 00734 set_prop_border_x_style_from_value (a_style, cur_term, 00735 DIR_BOTTOM) ; 00736 00737 cur_term = cur_term->next ; 00738 if (!cur_term || cur_term->type != TERM_IDENT) { 00739 return CR_OK ; 00740 } 00741 set_prop_border_x_style_from_value (a_style, cur_term, 00742 DIR_LEFT) ; 00743 return CR_OK ; 00744 } 00745 00746 static enum CRStatus 00747 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, 00748 enum CRDirection a_dir) 00749 { 00750 enum CRStatus status = CR_OK; 00751 CRNum *num_val = NULL; 00752 00753 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 00754 00755 switch (a_dir) { 00756 case DIR_TOP: 00757 num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv; 00758 break; 00759 00760 case DIR_RIGHT: 00761 num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv; 00762 break; 00763 00764 case DIR_BOTTOM: 00765 num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv; 00766 break; 00767 00768 case DIR_LEFT: 00769 num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv; 00770 break; 00771 00772 default: 00773 break; 00774 } 00775 00776 switch (a_value->type) { 00777 case TERM_IDENT: 00778 if (a_value->content.str 00779 && a_value->content.str->stryng 00780 && a_value->content.str->stryng->str 00781 && !strcmp (a_value->content.str->stryng->str, 00782 "inherit")) { 00783 status = cr_num_set (num_val, 0.0, NUM_INHERIT); 00784 } else if (a_value->content.str 00785 && a_value->content.str->stryng 00786 && !strcmp (a_value->content.str->stryng->str, 00787 "auto")) { 00788 status = cr_num_set (num_val, 0.0, NUM_AUTO); 00789 } else { 00790 status = CR_UNKNOWN_TYPE_ERROR; 00791 } 00792 break ; 00793 00794 case TERM_NUMBER: 00795 status = cr_num_copy (num_val, a_value->content.num); 00796 break; 00797 00798 default: 00799 status = CR_UNKNOWN_TYPE_ERROR; 00800 break; 00801 } 00802 00803 return status; 00804 } 00805 00806 struct CRPropDisplayValPair { 00807 const gchar *prop_name; 00808 enum CRDisplayType type; 00809 }; 00810 00811 static enum CRStatus 00812 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value) 00813 { 00814 static const struct CRPropDisplayValPair disp_vals_map[] = { 00815 {"none", DISPLAY_NONE}, 00816 {"inline", DISPLAY_INLINE}, 00817 {"block", DISPLAY_BLOCK}, 00818 {"run-in", DISPLAY_RUN_IN}, 00819 {"compact", DISPLAY_COMPACT}, 00820 {"marker", DISPLAY_MARKER}, 00821 {"table", DISPLAY_TABLE}, 00822 {"inline-table", DISPLAY_INLINE_TABLE}, 00823 {"table-row-group", DISPLAY_TABLE_ROW_GROUP}, 00824 {"table-header-group", DISPLAY_TABLE_HEADER_GROUP}, 00825 {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP}, 00826 {"table-row", DISPLAY_TABLE_ROW}, 00827 {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP}, 00828 {"table-column", DISPLAY_TABLE_COLUMN}, 00829 {"table-cell", DISPLAY_TABLE_CELL}, 00830 {"table-caption", DISPLAY_TABLE_CAPTION}, 00831 {"inherit", DISPLAY_INHERIT}, 00832 {NULL, DISPLAY_NONE} 00833 }; 00834 00835 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 00836 00837 switch (a_value->type) { 00838 case TERM_IDENT: 00839 { 00840 int i = 0; 00841 00842 if (!a_value->content.str 00843 || !a_value->content.str->stryng 00844 || !a_value->content.str->stryng->str) 00845 break; 00846 00847 for (i = 0; disp_vals_map[i].prop_name; i++) { 00848 if (!strncmp 00849 (disp_vals_map[i].prop_name, 00850 a_value->content.str->stryng->str, 00851 strlen (disp_vals_map[i].prop_name))) { 00852 a_style->display = 00853 disp_vals_map[i].type; 00854 break; 00855 } 00856 } 00857 } 00858 break; 00859 00860 default: 00861 break; 00862 } 00863 00864 return CR_OK; 00865 } 00866 00867 struct CRPropPositionValPair { 00868 const gchar *name; 00869 enum CRPositionType type; 00870 }; 00871 00872 static enum CRStatus 00873 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value) 00874 { 00875 enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR; 00876 static const struct CRPropPositionValPair position_vals_map[] = { 00877 {"static", POSITION_STATIC}, 00878 {"relative", POSITION_RELATIVE}, 00879 {"absolute", POSITION_ABSOLUTE}, 00880 {"fixed", POSITION_FIXED}, 00881 {"inherit", POSITION_INHERIT}, 00882 {NULL, POSITION_STATIC} 00883 /*must alwas be the last one */ 00884 }; 00885 00886 g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR); 00887 00888 switch (a_value->type) { 00889 case TERM_IDENT: 00890 { 00891 int i = 0; 00892 00893 if (!a_value->content.str 00894 || !a_value->content.str->stryng 00895 || !a_value->content.str->stryng->str) 00896 break; 00897 00898 for (i = 0; position_vals_map[i].name; i++) { 00899 if (!strncmp (position_vals_map[i].name, 00900 a_value->content.str->stryng->str, 00901 strlen (position_vals_map[i]. 00902 name))) { 00903 a_style->position = 00904 position_vals_map[i].type; 00905 status = CR_OK; 00906 break; 00907 } 00908 } 00909 } 00910 break; 00911 00912 default: 00913 break; 00914 } 00915 00916 return status; 00917 } 00918 00919 static enum CRStatus 00920 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, 00921 enum CRDirection a_dir) 00922 { 00923 CRNum *box_offset = NULL; 00924 00925 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 00926 00927 if (!(a_value->type == TERM_NUMBER) 00928 && !(a_value->type == TERM_IDENT)) { 00929 return CR_UNKNOWN_PROP_VAL_ERROR; 00930 } 00931 00932 switch (a_dir) { 00933 case DIR_TOP: 00934 box_offset = &a_style->num_props[NUM_PROP_TOP].sv; 00935 break; 00936 00937 case DIR_RIGHT: 00938 box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv; 00939 break; 00940 00941 case DIR_BOTTOM: 00942 box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv; 00943 break; 00944 case DIR_LEFT: 00945 box_offset = &a_style->num_props[NUM_PROP_LEFT].sv; 00946 break; 00947 00948 default: 00949 break; 00950 } 00951 00952 box_offset->type = NUM_AUTO; 00953 00954 if (a_value->type == TERM_NUMBER && a_value->content.num) { 00955 cr_num_copy (box_offset, a_value->content.num); 00956 } else if (a_value->type == TERM_IDENT 00957 && a_value->content.str 00958 && a_value->content.str->stryng 00959 && a_value->content.str->stryng->str) { 00960 if (!strncmp ("inherit", 00961 a_value->content.str->stryng->str, 00962 sizeof ("inherit")-1)) { 00963 cr_num_set (box_offset, 0.0, NUM_INHERIT); 00964 } else if (!strncmp ("auto", 00965 a_value->content.str->stryng->str, 00966 sizeof ("auto")-1)) { 00967 box_offset->type = NUM_AUTO; 00968 } 00969 } 00970 00971 return CR_OK; 00972 } 00973 00974 static enum CRStatus 00975 set_prop_float (CRStyle * a_style, CRTerm * a_value) 00976 { 00977 g_return_val_if_fail (a_style && a_value, 00978 CR_BAD_PARAM_ERROR); 00979 00980 /*the default float type as specified by the css2 spec */ 00981 a_style->float_type = FLOAT_NONE; 00982 00983 if (a_value->type != TERM_IDENT 00984 || !a_value->content.str 00985 || !a_value->content.str->stryng 00986 || !a_value->content.str->stryng->str) { 00987 /*unknown type, the float type is set to it's default value */ 00988 return CR_OK; 00989 } 00990 00991 if (!strncmp ("none", 00992 a_value->content.str->stryng->str, 00993 sizeof ("none")-1)) { 00994 a_style->float_type = FLOAT_NONE; 00995 } else if (!strncmp ("left", 00996 a_value->content.str->stryng->str, 00997 sizeof ("left")-1)) { 00998 a_style->float_type = FLOAT_LEFT; 00999 } else if (!strncmp ("right", 01000 a_value->content.str->stryng->str, 01001 sizeof ("right")-1)) { 01002 a_style->float_type = FLOAT_RIGHT; 01003 } else if (!strncmp ("inherit", 01004 a_value->content.str->stryng->str, 01005 sizeof ("inherit")-1)) { 01006 a_style->float_type = FLOAT_INHERIT; 01007 } 01008 return CR_OK; 01009 } 01010 01011 static enum CRStatus 01012 set_prop_width (CRStyle * a_style, CRTerm * a_value) 01013 { 01014 CRNum *width = NULL; 01015 g_return_val_if_fail (a_style 01016 && a_value, 01017 CR_BAD_PARAM_ERROR); 01018 01019 width = &a_style->num_props[NUM_PROP_WIDTH].sv; 01020 cr_num_set (width, 0.0, NUM_AUTO); 01021 01022 if (a_value->type == TERM_IDENT) { 01023 if (a_value->content.str 01024 && a_value->content.str->stryng 01025 && a_value->content.str->stryng->str) { 01026 if (!strncmp ("auto", 01027 a_value->content.str->stryng->str, 01028 sizeof ("auto")-1)) { 01029 cr_num_set (width, 0.0, NUM_AUTO); 01030 } else if (!strncmp ("inherit", 01031 a_value->content.str->stryng->str, 01032 sizeof ("inherit")-1)) { 01033 cr_num_set (width, 0.0, NUM_INHERIT); 01034 } 01035 } 01036 } else if (a_value->type == TERM_NUMBER) { 01037 if (a_value->content.num) { 01038 cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv, 01039 a_value->content.num); 01040 } 01041 } 01042 return CR_OK; 01043 } 01044 01045 static enum CRStatus 01046 set_prop_color (CRStyle * a_style, CRTerm * a_value) 01047 { 01048 enum CRStatus status = CR_OK; 01049 CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv; 01050 01051 g_return_val_if_fail (a_style 01052 && a_value, CR_BAD_PARAM_ERROR); 01053 01054 status = cr_rgb_set_from_term (a_rgb, a_value); 01055 01056 return status; 01057 } 01058 01059 static enum CRStatus 01060 set_prop_background_color (CRStyle * a_style, CRTerm * a_value) 01061 { 01062 enum CRStatus status = CR_OK; 01063 CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv; 01064 01065 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01066 01067 status = cr_rgb_set_from_term (rgb, a_value); 01068 return status; 01069 } 01070 01071 /** 01072 *Sets border-top-color, border-right-color, 01073 *border-bottom-color or border-left-color properties 01074 *in the style structure. The value is taken from a 01075 *css2 term of type IDENT or RGB. 01076 *@param a_style the style structure to set. 01077 *@param a_value the css2 term to take the color information from. 01078 *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM). 01079 *@return CR_OK upon successfull completion, an error code otherwise. 01080 */ 01081 static enum CRStatus 01082 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, 01083 enum CRDirection a_dir) 01084 { 01085 CRRgb *rgb_color = NULL; 01086 enum CRStatus status = CR_OK; 01087 01088 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01089 01090 switch (a_dir) { 01091 case DIR_TOP: 01092 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv; 01093 break; 01094 01095 case DIR_RIGHT: 01096 rgb_color = 01097 &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv; 01098 break; 01099 01100 case DIR_BOTTOM: 01101 rgb_color = 01102 &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv; 01103 break; 01104 01105 case DIR_LEFT: 01106 rgb_color = 01107 &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv; 01108 break; 01109 01110 default: 01111 cr_utils_trace_info ("unknown DIR type"); 01112 return CR_BAD_PARAM_ERROR; 01113 } 01114 01115 status = CR_UNKNOWN_PROP_VAL_ERROR; 01116 01117 if (a_value->type == TERM_IDENT) { 01118 if (a_value->content.str 01119 && a_value->content.str->stryng 01120 && a_value->content.str->stryng->str) { 01121 status = cr_rgb_set_from_name 01122 (rgb_color, 01123 (const guchar *) a_value->content.str->stryng->str); 01124 01125 } 01126 if (status != CR_OK) { 01127 cr_rgb_set_from_name (rgb_color, (const guchar *) "black"); 01128 } 01129 } else if (a_value->type == TERM_RGB) { 01130 if (a_value->content.rgb) { 01131 status = cr_rgb_set_from_rgb 01132 (rgb_color, a_value->content.rgb); 01133 } 01134 } 01135 return status; 01136 } 01137 01138 static enum CRStatus 01139 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, 01140 enum CRDirection a_dir) 01141 { 01142 CRTerm *cur_term = NULL; 01143 01144 enum CRStatus status = CR_OK; 01145 01146 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01147 01148 for (cur_term = a_value; 01149 cur_term; 01150 cur_term = cur_term->next) { 01151 status = set_prop_border_x_width_from_value (a_style, 01152 cur_term, a_dir); 01153 01154 if (status != CR_OK) { 01155 status = set_prop_border_x_style_from_value 01156 (a_style, cur_term, a_dir); 01157 } 01158 if (status != CR_OK) { 01159 status = set_prop_border_x_color_from_value 01160 (a_style, cur_term, a_dir); 01161 } 01162 } 01163 return CR_OK; 01164 } 01165 01166 static enum CRStatus 01167 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value) 01168 { 01169 enum CRDirection direction = 0; 01170 01171 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01172 01173 for (direction = 0; direction < NB_DIRS; direction++) { 01174 set_prop_border_x_from_value (a_style, 01175 a_value, 01176 direction); 01177 } 01178 01179 return CR_OK; 01180 } 01181 01182 static enum CRStatus 01183 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value) 01184 { 01185 CRTerm *cur_term = NULL; 01186 enum CRDirection direction = 0; 01187 enum CRStatus status = CR_OK; 01188 01189 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01190 01191 cur_term = a_value; 01192 01193 /*filter the eventual non NUMBER terms some user can have written here*/ 01194 while (cur_term && cur_term->type != TERM_NUMBER) { 01195 cur_term = cur_term->next; 01196 } 01197 if (!cur_term) 01198 return CR_ERROR ; 01199 01200 for (direction = 0; direction < NB_DIRS; direction++) { 01201 set_prop_padding_x_from_value (a_style, cur_term, direction); 01202 } 01203 cur_term = cur_term->next; 01204 01205 /*filter non NUMBER terms that some users can have written here...*/ 01206 while (cur_term && cur_term->type != TERM_NUMBER) { 01207 cur_term = cur_term->next; 01208 } 01209 /*the user can have just written padding: 1px*/ 01210 if (!cur_term) 01211 return CR_OK; 01212 01213 set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT); 01214 set_prop_padding_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_padding_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 status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT); 01230 return status; 01231 } 01232 01233 static enum CRStatus 01234 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value) 01235 { 01236 CRTerm *cur_term = NULL; 01237 enum CRDirection direction = 0; 01238 enum CRStatus status = CR_OK; 01239 01240 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01241 01242 cur_term = a_value; 01243 01244 while (cur_term && cur_term->type != TERM_NUMBER) { 01245 cur_term = cur_term->next; 01246 } 01247 01248 if (!cur_term) 01249 return CR_OK; 01250 01251 for (direction = 0; direction < NB_DIRS; direction++) { 01252 set_prop_margin_x_from_value (a_style, cur_term, direction); 01253 } 01254 cur_term = cur_term->next; 01255 01256 while (cur_term && cur_term->type != TERM_NUMBER) { 01257 cur_term = cur_term->next; 01258 } 01259 if (!cur_term) 01260 return CR_OK; 01261 01262 set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT); 01263 set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); 01264 01265 while (cur_term && cur_term->type != TERM_NUMBER) { 01266 cur_term = cur_term->next; 01267 } 01268 if (!cur_term) 01269 return CR_OK; 01270 01271 set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM); 01272 01273 while (cur_term && cur_term->type != TERM_NUMBER) { 01274 cur_term = cur_term->next; 01275 } 01276 if (!cur_term) 01277 return CR_OK; 01278 01279 status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); 01280 01281 return status; 01282 } 01283 01284 static enum CRStatus 01285 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value) 01286 { 01287 CRTerm *cur_term = NULL; 01288 CRFontFamily *font_family = NULL, 01289 *cur_ff = NULL, 01290 *cur_ff2 = NULL; 01291 01292 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01293 01294 if (a_value->type == TERM_IDENT && 01295 a_value->content.str && 01296 a_value->content.str->stryng && 01297 a_value->content.str->stryng->str && 01298 !strcmp ("inherit", a_value->content.str->stryng->str)) 01299 { 01300 font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL); 01301 goto out; 01302 } 01303 01304 for (cur_term = a_value; cur_term; cur_term = cur_term->next) { 01305 switch (cur_term->type) { 01306 case TERM_IDENT: 01307 { 01308 enum CRFontFamilyType font_type; 01309 01310 if (cur_term->content.str 01311 && cur_term->content.str->stryng 01312 && cur_term->content.str->stryng->str 01313 && !strcmp 01314 (cur_term->content.str->stryng->str, 01315 "sans-serif")) { 01316 font_type = FONT_FAMILY_SANS_SERIF; 01317 } else if (cur_term->content.str 01318 && cur_term->content.str->stryng 01319 && cur_term->content.str->stryng->str 01320 && !strcmp 01321 (cur_term->content.str->stryng->str, 01322 "serif")) { 01323 font_type = FONT_FAMILY_SERIF; 01324 } else if (cur_term->content.str 01325 && cur_term->content.str->stryng 01326 && cur_term->content.str->stryng->str 01327 && !strcmp (cur_term->content.str->stryng->str, 01328 "cursive")) { 01329 font_type = FONT_FAMILY_CURSIVE; 01330 } else if (cur_term->content.str 01331 && cur_term->content.str->stryng 01332 && cur_term->content.str->stryng->str 01333 && !strcmp (cur_term->content.str->stryng->str, 01334 "fantasy")) { 01335 font_type = FONT_FAMILY_FANTASY; 01336 } else if (cur_term->content.str 01337 && cur_term->content.str->stryng 01338 && cur_term->content.str->stryng->str 01339 && !strcmp (cur_term->content.str->stryng->str, 01340 "monospace")) { 01341 font_type = FONT_FAMILY_MONOSPACE; 01342 } else { 01343 /* 01344 *unknown property value. 01345 *ignore it. 01346 */ 01347 continue; 01348 } 01349 01350 cur_ff = cr_font_family_new (font_type, NULL); 01351 } 01352 break; 01353 01354 case TERM_STRING: 01355 { 01356 if (cur_term->content.str 01357 && cur_term->content.str->stryng 01358 && cur_term->content.str->stryng->str) { 01359 cur_ff = cr_font_family_new 01360 (FONT_FAMILY_NON_GENERIC, 01361 (guchar *) cur_term->content.str->stryng->str); 01362 } 01363 } 01364 break; 01365 01366 default: 01367 break; 01368 } 01369 01370 cur_ff2 = cr_font_family_append (font_family, cur_ff); 01371 if (cur_ff2) { 01372 font_family = cur_ff2; 01373 } 01374 } 01375 01376 out: 01377 if (font_family) { 01378 if (a_style->font_family) { 01379 cr_font_family_destroy (a_style->font_family); 01380 a_style->font_family = NULL ; 01381 } 01382 a_style->font_family = font_family; 01383 font_family = NULL ; 01384 } 01385 01386 return CR_OK; 01387 } 01388 01389 static enum CRStatus 01390 init_style_font_size_field (CRStyle * a_style) 01391 { 01392 g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR); 01393 01394 memset (&a_style->font_size, 0, 01395 sizeof (CRFontSizeVal)) ; 01396 /* 01397 if (!a_style->font_size) { 01398 a_style->font_size = cr_font_size_new (); 01399 if (!a_style->font_size) { 01400 return CR_INSTANCIATION_FAILED_ERROR; 01401 } 01402 } else { 01403 cr_font_size_clear (a_style->font_size); 01404 } 01405 */ 01406 return CR_OK; 01407 } 01408 01409 static enum CRStatus 01410 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value) 01411 { 01412 enum CRStatus status = CR_OK; 01413 01414 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01415 01416 switch (a_value->type) { 01417 case TERM_IDENT: 01418 if (a_value->content.str 01419 && a_value->content.str->stryng 01420 && a_value->content.str->stryng->str 01421 && !strcmp (a_value->content.str->stryng->str, 01422 "xx-small")) { 01423 status = init_style_font_size_field (a_style); 01424 g_return_val_if_fail (status == CR_OK, status); 01425 01426 a_style->font_size.sv.type = 01427 PREDEFINED_ABSOLUTE_FONT_SIZE; 01428 a_style->font_size.sv.value.predefined = 01429 FONT_SIZE_XX_SMALL; 01430 01431 } else if (a_value->content.str 01432 && a_value->content.str->stryng 01433 && a_value->content.str->stryng->str 01434 && !strcmp (a_value->content.str->stryng->str, 01435 "x-small")) { 01436 status = init_style_font_size_field (a_style); 01437 g_return_val_if_fail (status == CR_OK, status); 01438 01439 a_style->font_size.sv.type = 01440 PREDEFINED_ABSOLUTE_FONT_SIZE; 01441 a_style->font_size.sv.value.predefined = 01442 FONT_SIZE_X_SMALL; 01443 } else if (a_value->content.str 01444 && a_value->content.str->stryng 01445 && a_value->content.str->stryng->str 01446 && !strcmp (a_value->content.str->stryng->str, 01447 "small")) { 01448 status = init_style_font_size_field (a_style); 01449 g_return_val_if_fail (status == CR_OK, status); 01450 01451 a_style->font_size.sv.type = 01452 PREDEFINED_ABSOLUTE_FONT_SIZE; 01453 a_style->font_size.sv.value.predefined = 01454 FONT_SIZE_SMALL; 01455 } else if (a_value->content.str 01456 && a_value->content.str->stryng 01457 && a_value->content.str->stryng->str 01458 && !strcmp (a_value->content.str->stryng->str, "medium")) { 01459 status = init_style_font_size_field (a_style); 01460 g_return_val_if_fail (status == CR_OK, status); 01461 01462 a_style->font_size.sv.type = 01463 PREDEFINED_ABSOLUTE_FONT_SIZE; 01464 a_style->font_size.sv.value.predefined = 01465 FONT_SIZE_MEDIUM; 01466 } else if (a_value->content.str 01467 && a_value->content.str->stryng 01468 && a_value->content.str->stryng->str 01469 && !strcmp (a_value->content.str->stryng->str, 01470 "large")) { 01471 status = init_style_font_size_field (a_style); 01472 g_return_val_if_fail (status == CR_OK, status); 01473 01474 a_style->font_size.sv.type = 01475 PREDEFINED_ABSOLUTE_FONT_SIZE; 01476 a_style->font_size.sv.value.predefined = 01477 FONT_SIZE_LARGE; 01478 } else if (a_value->content.str 01479 && a_value->content.str->stryng 01480 && a_value->content.str->stryng->str 01481 && !strcmp (a_value->content.str->stryng->str, 01482 "x-large")) { 01483 status = init_style_font_size_field (a_style); 01484 g_return_val_if_fail (status == CR_OK, status); 01485 01486 a_style->font_size.sv.type = 01487 PREDEFINED_ABSOLUTE_FONT_SIZE; 01488 a_style->font_size.sv.value.predefined = 01489 FONT_SIZE_X_LARGE; 01490 } else if (a_value->content.str 01491 && a_value->content.str->stryng 01492 && a_value->content.str->stryng->str 01493 && !strcmp (a_value->content.str->stryng->str, 01494 "xx-large")) { 01495 status = init_style_font_size_field (a_style); 01496 g_return_val_if_fail (status == CR_OK, status); 01497 01498 a_style->font_size.sv.type = 01499 PREDEFINED_ABSOLUTE_FONT_SIZE; 01500 a_style->font_size.sv.value.predefined = 01501 FONT_SIZE_XX_LARGE; 01502 } else if (a_value->content.str 01503 && a_value->content.str->stryng 01504 && a_value->content.str->stryng->str 01505 && !strcmp (a_value->content.str->stryng->str, 01506 "larger")) { 01507 status = init_style_font_size_field (a_style); 01508 g_return_val_if_fail (status == CR_OK, status); 01509 01510 a_style->font_size.sv.type = RELATIVE_FONT_SIZE; 01511 a_style->font_size.sv.value.relative = FONT_SIZE_LARGER; 01512 } else if (a_value->content.str 01513 && a_value->content.str->stryng 01514 && a_value->content.str->stryng->str 01515 && !strcmp (a_value->content.str->stryng->str, 01516 "smaller")) { 01517 status = init_style_font_size_field (a_style); 01518 g_return_val_if_fail (status == CR_OK, status); 01519 01520 a_style->font_size.sv.type = RELATIVE_FONT_SIZE; 01521 a_style->font_size.sv.value.relative = 01522 FONT_SIZE_SMALLER; 01523 } else if (a_value->content.str 01524 && a_value->content.str->stryng 01525 && a_value->content.str->stryng->str 01526 && !strcmp (a_value->content.str->stryng->str, "inherit")) { 01527 status = init_style_font_size_field (a_style); 01528 g_return_val_if_fail (status == CR_OK, status); 01529 a_style->font_size.sv.type = INHERITED_FONT_SIZE; 01530 01531 } else { 01532 cr_utils_trace_info ("Unknown value of font-size") ; 01533 status = init_style_font_size_field (a_style); 01534 return CR_UNKNOWN_PROP_VAL_ERROR; 01535 } 01536 break; 01537 01538 case TERM_NUMBER: 01539 if (a_value->content.num) { 01540 status = init_style_font_size_field (a_style); 01541 g_return_val_if_fail (status == CR_OK, status); 01542 01543 a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE; 01544 cr_num_copy (&a_style->font_size.sv.value.absolute, 01545 a_value->content.num) ; 01546 } 01547 break; 01548 01549 default: 01550 status = init_style_font_size_field (a_style); 01551 return CR_UNKNOWN_PROP_VAL_ERROR; 01552 } 01553 return CR_OK; 01554 } 01555 01556 static enum CRStatus 01557 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value) 01558 { 01559 enum CRStatus status = CR_OK; 01560 01561 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01562 01563 switch (a_value->type) { 01564 case TERM_IDENT: 01565 if (a_value->content.str 01566 && a_value->content.str->stryng 01567 && a_value->content.str->stryng->str) { 01568 if (!strcmp (a_value->content.str->stryng->str, "normal")) { 01569 a_style->font_style = FONT_STYLE_NORMAL; 01570 } else if (!strcmp 01571 (a_value->content.str->stryng->str, 01572 "italic")) { 01573 a_style->font_style = FONT_STYLE_ITALIC; 01574 } else if (!strcmp 01575 (a_value->content.str->stryng->str, 01576 "oblique")) { 01577 a_style->font_style = FONT_STYLE_OBLIQUE; 01578 } else if (!strcmp 01579 (a_value->content.str->stryng->str, 01580 "inherit")) { 01581 a_style->font_style = FONT_STYLE_INHERIT; 01582 } else { 01583 status = CR_UNKNOWN_PROP_VAL_ERROR; 01584 } 01585 } 01586 break; 01587 01588 default: 01589 status = CR_UNKNOWN_PROP_VAL_ERROR; 01590 break; 01591 } 01592 01593 return status; 01594 } 01595 01596 static enum CRStatus 01597 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value) 01598 { 01599 enum CRStatus status = CR_OK; 01600 01601 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01602 01603 switch (a_value->type) { 01604 case TERM_IDENT: 01605 if (a_value->content.str 01606 && a_value->content.str->stryng 01607 && a_value->content.str->stryng->str) { 01608 if (!strcmp (a_value->content.str->stryng->str, 01609 "normal")) { 01610 a_style->font_weight = FONT_WEIGHT_NORMAL; 01611 } else if (!strcmp (a_value->content.str->stryng->str, 01612 "bold")) { 01613 a_style->font_weight = FONT_WEIGHT_BOLD; 01614 } else if (!strcmp (a_value->content.str->stryng->str, 01615 "bolder")) { 01616 a_style->font_weight = FONT_WEIGHT_BOLDER; 01617 } else if (!strcmp (a_value->content.str->stryng->str, 01618 "lighter")) { 01619 a_style->font_weight = FONT_WEIGHT_LIGHTER; 01620 } else if (!strcmp (a_value->content.str->stryng->str, 01621 "inherit")) { 01622 a_style->font_weight = FONT_WEIGHT_INHERIT; 01623 01624 } else { 01625 status = CR_UNKNOWN_PROP_VAL_ERROR; 01626 } 01627 01628 } 01629 break; 01630 01631 case TERM_NUMBER: 01632 if (a_value->content.num 01633 && (a_value->content.num->type == NUM_GENERIC 01634 || a_value->content.num->type == NUM_AUTO)) { 01635 if (a_value->content.num->val <= 150) { 01636 a_style->font_weight = FONT_WEIGHT_100; 01637 } else if (a_value->content.num->val <= 250) { 01638 a_style->font_weight = FONT_WEIGHT_200; 01639 } else if (a_value->content.num->val <= 350) { 01640 a_style->font_weight = FONT_WEIGHT_300; 01641 } else if (a_value->content.num->val <= 450) { 01642 a_style->font_weight = FONT_WEIGHT_400; 01643 } else if (a_value->content.num->val <= 550) { 01644 a_style->font_weight = FONT_WEIGHT_500; 01645 } else if (a_value->content.num->val <= 650) { 01646 a_style->font_weight = FONT_WEIGHT_600; 01647 } else if (a_value->content.num->val <= 750) { 01648 a_style->font_weight = FONT_WEIGHT_700; 01649 } else if (a_value->content.num->val <= 850) { 01650 a_style->font_weight = FONT_WEIGHT_800; 01651 } else { 01652 a_style->font_weight = FONT_WEIGHT_900; 01653 } 01654 } 01655 break; 01656 01657 default: 01658 status = CR_UNKNOWN_PROP_VAL_ERROR; 01659 break; 01660 } 01661 01662 return status; 01663 } 01664 01665 static enum CRStatus 01666 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value) 01667 { 01668 enum CRStatus status = CR_OK; 01669 01670 g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); 01671 01672 switch (a_value->type) { 01673 case TERM_IDENT: 01674 if (a_value->content.str && a_value->content.str->stryng) { 01675 if (!strcmp (a_value->content.str->stryng->str, "normal")) { 01676 a_style->white_space = WHITE_SPACE_NORMAL; 01677 } else if (!strcmp (a_value->content.str->stryng->str, 01678 "pre")) { 01679 a_style->white_space = WHITE_SPACE_PRE; 01680 } else if (!strcmp (a_value->content.str->stryng->str, 01681 "nowrap")) { 01682 a_style->white_space = WHITE_SPACE_NOWRAP; 01683 } else if (!strcmp (a_value->content.str->stryng->str, 01684 "inherit")) { 01685 a_style->white_space = WHITE_SPACE_INHERIT; 01686 } else { 01687 status = CR_UNKNOWN_PROP_VAL_ERROR; 01688 } 01689 } 01690 break; 01691 default: 01692 status = CR_UNKNOWN_PROP_VAL_ERROR; 01693 break; 01694 } 01695 01696 return status; 01697 } 01698 01699 /****************** 01700 *Public methods 01701 ******************/ 01702 01703 /** 01704 *Default constructor of #CRStyle. 01705 *@param a_set_props_to_initial_values if TRUE, the style properties 01706 *will be set to the default values. Only the style properties of the 01707 *root box should be set to their initial values. 01708 *Otherwise, the style values are set to their default value. 01709 *Read the CSS2 spec, chapters 6.1.1 to 6.2. 01710 */ 01711 CRStyle * 01712 cr_style_new (gboolean a_set_props_to_initial_values) 01713 { 01714 CRStyle *result = NULL; 01715 01716 result = g_try_malloc (sizeof (CRStyle)); 01717 if (!result) { 01718 cr_utils_trace_info ("Out of memory"); 01719 return NULL; 01720 } 01721 memset (result, 0, sizeof (CRStyle)); 01722 gv_prop_hash_ref_count++; 01723 01724 if (a_set_props_to_initial_values == TRUE) { 01725 cr_style_set_props_to_initial_values (result); 01726 } else { 01727 cr_style_set_props_to_default_values (result); 01728 } 01729 01730 return result; 01731 } 01732 01733 /** 01734 *Sets the style properties to their default values according to the css2 spec 01735 * i.e inherit if the property is inherited, its initial value otherwise. 01736 *@param a_this the current instance of #CRStyle. 01737 *@return CR_OK upon successfull completion, an error code otherwise. 01738 */ 01739 enum CRStatus 01740 cr_style_set_props_to_default_values (CRStyle * a_this) 01741 { 01742 glong i = 0; 01743 01744 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); 01745 01746 for (i = 0; i < NB_NUM_PROPS; i++) 01747 { 01748 switch (i) 01749 { 01750 case NUM_PROP_WIDTH: 01751 case NUM_PROP_TOP: 01752 case NUM_PROP_RIGHT: 01753 case NUM_PROP_BOTTOM: 01754 case NUM_PROP_LEFT: 01755 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); 01756 break; 01757 01758 case NUM_PROP_PADDING_TOP: 01759 case NUM_PROP_PADDING_RIGHT: 01760 case NUM_PROP_PADDING_BOTTOM: 01761 case NUM_PROP_PADDING_LEFT: 01762 case NUM_PROP_BORDER_TOP: 01763 case NUM_PROP_BORDER_RIGHT: 01764 case NUM_PROP_BORDER_BOTTOM: 01765 case NUM_PROP_BORDER_LEFT: 01766 case NUM_PROP_MARGIN_TOP: 01767 case NUM_PROP_MARGIN_RIGHT: 01768 case NUM_PROP_MARGIN_BOTTOM: 01769 case NUM_PROP_MARGIN_LEFT: 01770 cr_num_set (&a_this->num_props[i].sv, 01771 0, NUM_LENGTH_PX); 01772 break; 01773 01774 default: 01775 cr_utils_trace_info ("Unknown property"); 01776 break; 01777 } 01778 } 01779 01780 for (i = 0; i < NB_RGB_PROPS; i++) { 01781 01782 switch (i) { 01783 /*default foreground color is black */ 01784 case RGB_PROP_COLOR: 01785 /* 01786 *REVIEW: color is inherited and the default value is 01787 *ua dependant. 01788 */ 01789 cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv, 01790 TRUE) ; 01791 break; 01792 01793 /*default background color is white */ 01794 case RGB_PROP_BACKGROUND_COLOR: 01795 /* TODO: the default value should be transparent */ 01796 cr_rgb_set (&a_this->rgb_props[i].sv, 01797 255, 255, 255, FALSE); 01798 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, 01799 TRUE) ; 01800 break; 01801 01802 default: 01803 /* 01804 *TODO: for BORDER_COLOR the initial value should 01805 * be the same as COLOR 01806 */ 01807 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, 01808 FALSE); 01809 break; 01810 } 01811 } 01812 01813 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { 01814 a_this->border_style_props[i] = BORDER_STYLE_NONE; 01815 } 01816 01817 a_this->display = DISPLAY_INLINE; 01818 a_this->position = POSITION_STATIC; 01819 a_this->float_type = FLOAT_NONE; 01820 a_this->parent_style = NULL; 01821 a_this->font_style = FONT_STYLE_INHERIT; 01822 a_this->font_variant = FONT_VARIANT_INHERIT; 01823 a_this->font_weight = FONT_WEIGHT_INHERIT; 01824 a_this->font_family = NULL; 01825 01826 cr_font_size_set_to_inherit (&a_this->font_size.sv) ; 01827 cr_font_size_clear (&a_this->font_size.cv) ; 01828 cr_font_size_clear (&a_this->font_size.av) ; 01829 01830 /* To make the inheritance resolution possible and efficient */ 01831 a_this->inherited_props_resolved = FALSE ; 01832 return CR_OK; 01833 } 01834 01835 /** 01836 *Sets the style properties to their initial value according to the css2 spec. 01837 *This function should be used to initialize the style of the root element 01838 *of an xml tree. 01839 *Some properties are user agent dependant like font-family, and 01840 *are not initialized, read the spec to make you renderer compliant. 01841 *@param a_this the current instance of #CRStyle. 01842 *@return CR_OK upon successfull completion, an error code otherwise. 01843 */ 01844 enum CRStatus 01845 cr_style_set_props_to_initial_values (CRStyle *a_this) 01846 { 01847 glong i = 0; 01848 01849 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); 01850 01851 for (i = 0; i < NB_NUM_PROPS; i++) { 01852 switch (i) { 01853 case NUM_PROP_WIDTH: 01854 cr_num_set (&a_this->num_props[i].sv, 800, 01855 NUM_LENGTH_PX) ; 01856 break ; 01857 case NUM_PROP_TOP: 01858 case NUM_PROP_RIGHT: 01859 case NUM_PROP_BOTTOM: 01860 case NUM_PROP_LEFT: 01861 cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); 01862 break; 01863 01864 case NUM_PROP_PADDING_TOP: 01865 case NUM_PROP_PADDING_RIGHT: 01866 case NUM_PROP_PADDING_BOTTOM: 01867 case NUM_PROP_PADDING_LEFT: 01868 case NUM_PROP_BORDER_TOP: 01869 case NUM_PROP_BORDER_RIGHT: 01870 case NUM_PROP_BORDER_BOTTOM: 01871 case NUM_PROP_BORDER_LEFT: 01872 case NUM_PROP_MARGIN_TOP: 01873 case NUM_PROP_MARGIN_RIGHT: 01874 case NUM_PROP_MARGIN_BOTTOM: 01875 case NUM_PROP_MARGIN_LEFT: 01876 cr_num_set (&a_this->num_props[i].sv, 01877 0, NUM_LENGTH_PX); 01878 break; 01879 01880 default: 01881 cr_utils_trace_info ("Unknown property"); 01882 break; 01883 } 01884 } 01885 01886 for (i = 0; i < NB_RGB_PROPS; i++) { 01887 01888 switch (i) { 01889 /*default foreground color is black */ 01890 case RGB_PROP_COLOR: 01891 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); 01892 break; 01893 01894 /*default background color is white */ 01895 case RGB_PROP_BACKGROUND_COLOR: 01896 cr_rgb_set (&a_this->rgb_props[i].sv, 01897 255, 255, 255, FALSE); 01898 cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, 01899 TRUE) ; 01900 break; 01901 default: 01902 cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); 01903 break; 01904 } 01905 } 01906 01907 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { 01908 a_this->border_style_props[i] = BORDER_STYLE_NONE; 01909 } 01910 01911 a_this->display = DISPLAY_BLOCK; 01912 a_this->position = POSITION_STATIC; 01913 a_this->float_type = FLOAT_NONE; 01914 a_this->font_style = FONT_STYLE_NORMAL; 01915 a_this->font_variant = FONT_VARIANT_NORMAL; 01916 a_this->font_weight = FONT_WEIGHT_NORMAL; 01917 a_this->font_stretch = FONT_STRETCH_NORMAL; 01918 a_this->white_space = WHITE_SPACE_NORMAL; 01919 cr_font_size_set_predefined_absolute_font_size 01920 (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ; 01921 a_this->inherited_props_resolved = FALSE ; 01922 01923 return CR_OK; 01924 } 01925 01926 /** 01927 *Resolves the inherited properties. 01928 *The function sets the "inherited" properties to either the value of 01929 *their parent properties. 01930 *This function is *NOT* recursive. So the inherited properties of 01931 *the parent style must have been resolved prior to calling this function. 01932 *@param a_this the instance where 01933 *@return CR_OK if a root node is found and the propagation is successful, 01934 *an error code otherwise 01935 */ 01936 enum CRStatus 01937 cr_style_resolve_inherited_properties (CRStyle *a_this) 01938 { 01939 enum CRStatus ret = CR_OK; 01940 glong i = 0; 01941 01942 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); 01943 g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ; 01944 01945 if (a_this->inherited_props_resolved == TRUE) 01946 return CR_OK ; 01947 01948 for (i=0 ; i < NB_NUM_PROPS ;i++) { 01949 if (a_this->num_props[i].sv.type == NUM_INHERIT) { 01950 cr_num_copy (&a_this->num_props[i].cv, 01951 &a_this->parent_style->num_props[i].cv); 01952 } 01953 } 01954 for (i=0; i < NB_RGB_PROPS; i++) { 01955 if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) { 01956 cr_rgb_copy ( 01957 &a_this->rgb_props[i].cv, 01958 &a_this->parent_style->rgb_props[i].cv); 01959 } 01960 } 01961 for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { 01962 if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) { 01963 a_this->border_style_props[i] = 01964 a_this->parent_style->border_style_props[i]; 01965 } 01966 } 01967 01968 if (a_this->display == DISPLAY_INHERIT) { 01969 a_this->display = a_this->parent_style->display; 01970 } 01971 if (a_this->position == POSITION_INHERIT) { 01972 a_this->position = a_this->parent_style->position; 01973 } 01974 if (a_this->float_type == FLOAT_INHERIT) { 01975 a_this->float_type = a_this->parent_style->float_type; 01976 } 01977 if (a_this->font_style == FONT_STYLE_INHERIT) { 01978 a_this->font_style = a_this->parent_style->font_style; 01979 } 01980 if (a_this->font_variant == FONT_VARIANT_INHERIT) { 01981 a_this->font_variant = a_this->parent_style->font_variant; 01982 } 01983 if (a_this->font_weight == FONT_WEIGHT_INHERIT) { 01984 a_this->font_weight = a_this->parent_style->font_weight; 01985 } 01986 if (a_this->font_stretch == FONT_STRETCH_INHERIT) { 01987 a_this->font_stretch = a_this->parent_style->font_stretch; 01988 } 01989 /*NULL is inherit marker for font_famiy*/ 01990 if (a_this->font_family == NULL) { 01991 a_this->font_family = a_this->parent_style->font_family; 01992 } 01993 if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) { 01994 cr_font_size_copy (&a_this->font_size.cv, 01995 &a_this->parent_style->font_size.cv) ; 01996 } 01997 a_this->inherited_props_resolved = TRUE ; 01998 return ret; 01999 } 02000 02001 /** 02002 *Walks through a css2 property declaration, and populated the 02003 *according field(s) in the #CRStyle structure. 02004 *If the properties or their value(s) are/is not known, 02005 *sets the corresponding field(s) of #CRStyle to its/their default 02006 *value(s) 02007 *@param a_this the instance of #CRStyle to set. 02008 *@param a_decl the declaration from which the #CRStyle fields are set. 02009 *@return CR_OK upon successfull completion, an error code otherwise. 02010 */ 02011 enum CRStatus 02012 cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl) 02013 { 02014 CRTerm *value = NULL; 02015 enum CRStatus status = CR_OK; 02016 02017 enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN; 02018 02019 g_return_val_if_fail (a_this && a_decl 02020 && a_decl 02021 && a_decl->property 02022 && a_decl->property->stryng 02023 && a_decl->property->stryng->str, 02024 CR_BAD_PARAM_ERROR); 02025 02026 prop_id = cr_style_get_prop_id 02027 ((const guchar *) a_decl->property->stryng->str); 02028 02029 value = a_decl->value; 02030 switch (prop_id) { 02031 case PROP_ID_PADDING_TOP: 02032 status = set_prop_padding_x_from_value 02033 (a_this, value, DIR_TOP); 02034 break; 02035 02036 case PROP_ID_PADDING_RIGHT: 02037 status = set_prop_padding_x_from_value 02038 (a_this, value, DIR_RIGHT); 02039 break; 02040 case PROP_ID_PADDING_BOTTOM: 02041 status = set_prop_padding_x_from_value 02042 (a_this, value, DIR_BOTTOM); 02043 break; 02044 02045 case PROP_ID_PADDING_LEFT: 02046 status = set_prop_padding_x_from_value 02047 (a_this, value, DIR_LEFT); 02048 break; 02049 02050 case PROP_ID_PADDING: 02051 status = set_prop_padding_from_value (a_this, value) ; 02052 break; 02053 02054 case PROP_ID_BORDER_TOP_WIDTH: 02055 status = set_prop_border_x_width_from_value (a_this, value, 02056 DIR_TOP); 02057 break; 02058 02059 case PROP_ID_BORDER_RIGHT_WIDTH: 02060 status = set_prop_border_x_width_from_value (a_this, value, 02061 DIR_RIGHT); 02062 break; 02063 02064 case PROP_ID_BORDER_BOTTOM_WIDTH: 02065 status = set_prop_border_x_width_from_value (a_this, value, 02066 DIR_BOTTOM); 02067 break; 02068 02069 case PROP_ID_BORDER_LEFT_WIDTH: 02070 status = set_prop_border_x_width_from_value (a_this, value, 02071 DIR_LEFT); 02072 break; 02073 02074 case PROP_ID_BORDER_WIDTH: 02075 status = set_prop_border_width_from_value (a_this, value) ; 02076 break ; 02077 02078 case PROP_ID_BORDER_TOP_STYLE: 02079 status = set_prop_border_x_style_from_value (a_this, value, 02080 DIR_TOP); 02081 break; 02082 02083 case PROP_ID_BORDER_RIGHT_STYLE: 02084 status = set_prop_border_x_style_from_value (a_this, value, 02085 DIR_RIGHT); 02086 break; 02087 02088 case PROP_ID_BORDER_BOTTOM_STYLE: 02089 status = set_prop_border_x_style_from_value (a_this, value, 02090 DIR_BOTTOM); 02091 break; 02092 02093 case PROP_ID_BORDER_LEFT_STYLE: 02094 status = set_prop_border_x_style_from_value (a_this, value, 02095 DIR_LEFT); 02096 break; 02097 02098 case PROP_ID_BORDER_STYLE: 02099 status = set_prop_border_style_from_value (a_this, value) ; 02100 break ; 02101 02102 case PROP_ID_BORDER_TOP_COLOR: 02103 status = set_prop_border_x_color_from_value (a_this, value, 02104 DIR_TOP); 02105 break; 02106 02107 case PROP_ID_BORDER_RIGHT_COLOR: 02108 status = set_prop_border_x_color_from_value (a_this, value, 02109 DIR_RIGHT); 02110 break; 02111 02112 case PROP_ID_BORDER_BOTTOM_COLOR: 02113 status = set_prop_border_x_color_from_value (a_this, value, 02114 DIR_BOTTOM); 02115 break; 02116 02117 case PROP_ID_BORDER_LEFT_COLOR: 02118 status = set_prop_border_x_color_from_value (a_this, value, 02119 DIR_BOTTOM); 02120 break; 02121 02122 case PROP_ID_BORDER_TOP: 02123 status = set_prop_border_x_from_value (a_this, value, 02124 DIR_TOP); 02125 break; 02126 02127 case PROP_ID_BORDER_RIGHT: 02128 status = set_prop_border_x_from_value (a_this, value, 02129 DIR_RIGHT); 02130 break; 02131 02132 case PROP_ID_BORDER_BOTTOM: 02133 status = set_prop_border_x_from_value (a_this, value, 02134 DIR_BOTTOM); 02135 break; 02136 02137 case PROP_ID_BORDER_LEFT: 02138 status = set_prop_border_x_from_value (a_this, value, 02139 DIR_LEFT); 02140 break; 02141 02142 case PROP_ID_MARGIN_TOP: 02143 status = set_prop_margin_x_from_value (a_this, value, 02144 DIR_TOP); 02145 break; 02146 02147 case PROP_ID_BORDER: 02148 status = set_prop_border_from_value (a_this, value); 02149 break; 02150 02151 case PROP_ID_MARGIN_RIGHT: 02152 status = set_prop_margin_x_from_value (a_this, value, 02153 DIR_RIGHT); 02154 break; 02155 02156 case PROP_ID_MARGIN_BOTTOM: 02157 status = set_prop_margin_x_from_value (a_this, value, 02158 DIR_BOTTOM); 02159 break; 02160 02161 case PROP_ID_MARGIN_LEFT: 02162 status = set_prop_margin_x_from_value (a_this, value, 02163 DIR_LEFT); 02164 break; 02165 02166 case PROP_ID_MARGIN: 02167 status = set_prop_margin_from_value (a_this, value); 02168 break; 02169 02170 case PROP_ID_DISPLAY: 02171 status = set_prop_display_from_value (a_this, value); 02172 break; 02173 02174 case PROP_ID_POSITION: 02175 status = set_prop_position_from_value (a_this, value); 02176 break; 02177 02178 case PROP_ID_TOP: 02179 status = set_prop_x_from_value (a_this, value, DIR_TOP); 02180 break; 02181 02182 case PROP_ID_RIGHT: 02183 status = set_prop_x_from_value (a_this, value, DIR_RIGHT); 02184 break; 02185 02186 case PROP_ID_BOTTOM: 02187 status = set_prop_x_from_value (a_this, value, DIR_BOTTOM); 02188 break; 02189 02190 case PROP_ID_LEFT: 02191 status = set_prop_x_from_value (a_this, value, DIR_LEFT); 02192 break; 02193 02194 case PROP_ID_FLOAT: 02195 status = set_prop_float (a_this, value); 02196 break; 02197 02198 case PROP_ID_WIDTH: 02199 status = set_prop_width (a_this, value); 02200 break; 02201 02202 case PROP_ID_COLOR: 02203 status = set_prop_color (a_this, value); 02204 break; 02205 02206 case PROP_ID_BACKGROUND_COLOR: 02207 status = set_prop_background_color (a_this, value); 02208 break; 02209 02210 case PROP_ID_FONT_FAMILY: 02211 status = set_prop_font_family_from_value (a_this, value); 02212 break; 02213 02214 case PROP_ID_FONT_SIZE: 02215 status = set_prop_font_size_from_value (a_this, value); 02216 break; 02217 02218 case PROP_ID_FONT_STYLE: 02219 status = set_prop_font_style_from_value (a_this, value); 02220 break; 02221 02222 case PROP_ID_FONT_WEIGHT: 02223 status = set_prop_font_weight_from_value (a_this, value); 02224 break; 02225 02226 case PROP_ID_WHITE_SPACE: 02227 status = set_prop_white_space_from_value(a_this, value); 02228 break; 02229 02230 default: 02231 return CR_UNKNOWN_TYPE_ERROR; 02232 02233 } 02234 02235 return status; 02236 } 02237 02238 /** 02239 *Increases the reference count 02240 *of the current instance of #CRStyle. 02241 *@param a_this the current instance of #CRStyle. 02242 *@return CR_OK upon successfull completion, an error code 02243 *otherwise. 02244 */ 02245 enum CRStatus 02246 cr_style_ref (CRStyle * a_this) 02247 { 02248 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); 02249 02250 a_this->ref_count++; 02251 return CR_OK; 02252 } 02253 02254 /** 02255 *Decreases the reference count of 02256 *the current instance of #CRStyle. 02257 *If the reference count reaches 0, the 02258 *instance of #CRStyle is destoyed. 02259 *@param a_this the current instance of #CRStyle. 02260 *@return TRUE if the instance has been destroyed, FALSE 02261 *otherwise. 02262 */ 02263 gboolean 02264 cr_style_unref (CRStyle * a_this) 02265 { 02266 g_return_val_if_fail (a_this, FALSE); 02267 02268 if (a_this->ref_count) 02269 a_this->ref_count--; 02270 02271 if (!a_this->ref_count) { 02272 cr_style_destroy (a_this); 02273 return TRUE; 02274 } 02275 02276 return FALSE; 02277 } 02278 02279 /** 02280 *Duplicates the current instance of #CRStyle . 02281 *The newly created instance of #CRStyle must be 02282 *freed using cr_style_destroy (). 02283 *@param a_this the current instance of #CRStyle. 02284 *@return the newly duplicated instance of #CRStyle. 02285 */ 02286 CRStyle * 02287 cr_style_dup (CRStyle * a_this) 02288 { 02289 CRStyle *result = NULL; 02290 02291 g_return_val_if_fail (a_this, NULL); 02292 02293 result = cr_style_new (FALSE); 02294 if (!result) { 02295 cr_utils_trace_info ("Out of memory"); 02296 return NULL; 02297 } 02298 cr_style_copy (result, a_this); 02299 return result; 02300 } 02301 02302 /** 02303 *Copies a style data structure into another. 02304 *TODO: this is actually broken because it's based 02305 *on memcpy although some data stuctures of CRStyle should 02306 *be properly duplicated. 02307 *@param a_dest the destination style datastructure 02308 *@param a_src the source style datastructure. 02309 *@return CR_OK upon succesfull completion, an error code otherwise 02310 */ 02311 enum CRStatus 02312 cr_style_copy (CRStyle * a_dest, CRStyle * a_src) 02313 { 02314 g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR); 02315 02316 memcpy (a_dest, a_src, sizeof (CRStyle)); 02317 return CR_OK; 02318 } 02319 02320 /** 02321 *dump a CRNumpPropVal in a string. 02322 *@param a_prop_val the numerical property value to dump 02323 *@param a_str the string to dump the numerical propertie into. 02324 *Note that the string value is appended to a_str. 02325 *@param a_nb_indent the number white chars of indentation. 02326 */ 02327 enum CRStatus 02328 cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val, 02329 GString * a_str, guint a_nb_indent) 02330 { 02331 enum CRStatus status = CR_OK; 02332 guchar *tmp_str = NULL; 02333 GString *str = NULL; 02334 02335 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); 02336 02337 str = g_string_new (NULL); 02338 cr_utils_dump_n_chars2 (' ', str, a_nb_indent); 02339 g_string_append (str, "NumPropVal {"); 02340 tmp_str = cr_num_to_string (&a_prop_val->sv); 02341 if (!tmp_str) { 02342 status = CR_ERROR; 02343 goto cleanup; 02344 } 02345 g_string_append_printf (str, "sv: %s ", tmp_str); 02346 g_free (tmp_str); 02347 tmp_str = NULL; 02348 02349 tmp_str = cr_num_to_string (&a_prop_val->cv); 02350 if (!tmp_str) { 02351 status = CR_ERROR; 02352 goto cleanup; 02353 } 02354 g_string_append_printf (str, "cv: %s ", tmp_str); 02355 g_free (tmp_str); 02356 tmp_str = NULL; 02357 02358 tmp_str = cr_num_to_string (&a_prop_val->av); 02359 if (!tmp_str) { 02360 status = CR_ERROR; 02361 goto cleanup; 02362 } 02363 g_string_append_printf (str, "av: %s ", tmp_str); 02364 g_free (tmp_str); 02365 tmp_str = NULL; 02366 g_string_append (str, "}"); 02367 g_string_append (a_str, str->str); 02368 status = CR_OK; 02369 cleanup: 02370 02371 if (tmp_str) { 02372 g_free (tmp_str); 02373 tmp_str = NULL; 02374 } 02375 if (str) { 02376 g_string_free (str, TRUE); 02377 } 02378 return status; 02379 } 02380 02381 enum CRStatus 02382 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val, 02383 GString * a_str, guint a_nb_indent) 02384 { 02385 enum CRStatus status = CR_OK; 02386 guchar *tmp_str = NULL; 02387 GString *str = NULL; 02388 02389 g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); 02390 02391 str = g_string_new (NULL); 02392 02393 cr_utils_dump_n_chars2 (' ', str, a_nb_indent); 02394 g_string_append (str, "RGBPropVal {"); 02395 tmp_str = cr_rgb_to_string (&a_prop_val->sv); 02396 if (!tmp_str) { 02397 status = CR_ERROR; 02398 goto cleanup; 02399 } 02400 g_string_append_printf (str, "sv: %s ", tmp_str); 02401 g_free (tmp_str); 02402 tmp_str = NULL; 02403 tmp_str = cr_rgb_to_string (&a_prop_val->cv); 02404 if (!tmp_str) { 02405 status = CR_ERROR; 02406 goto cleanup; 02407 } 02408 g_string_append_printf (str, "cv: %s ", tmp_str); 02409 g_free (tmp_str); 02410 tmp_str = NULL; 02411 tmp_str = cr_rgb_to_string (&a_prop_val->av); 02412 if (!tmp_str) { 02413 status = CR_ERROR; 02414 goto cleanup; 02415 } 02416 g_string_append_printf (str, "av: %s ", tmp_str); 02417 g_free (tmp_str); 02418 tmp_str = NULL; 02419 02420 g_string_append (str, "}"); 02421 g_string_append (a_str, str->str); 02422 status = CR_OK; 02423 cleanup: 02424 02425 if (tmp_str) { 02426 g_free (tmp_str); 02427 tmp_str = NULL; 02428 } 02429 if (str) { 02430 g_string_free (str, TRUE); 02431 } 02432 return status; 02433 } 02434 02435 enum CRStatus 02436 cr_style_border_style_to_string (enum CRBorderStyle a_prop, 02437 GString * a_str, guint a_nb_indent) 02438 { 02439 gchar *str = NULL; 02440 02441 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); 02442 02443 switch (a_prop) { 02444 case BORDER_STYLE_NONE: 02445 str = (gchar *) "border-style-none"; 02446 break; 02447 case BORDER_STYLE_HIDDEN: 02448 str = (gchar *) "border-style-hidden"; 02449 break; 02450 case BORDER_STYLE_DOTTED: 02451 str = (gchar *) "border-style-dotted"; 02452 break; 02453 case BORDER_STYLE_DASHED: 02454 str = (gchar *) "border-style-dashed"; 02455 break; 02456 case BORDER_STYLE_SOLID: 02457 str = (gchar *) "border-style-solid"; 02458 break; 02459 case BORDER_STYLE_DOUBLE: 02460 str = (gchar *) "border-style-double"; 02461 break; 02462 case BORDER_STYLE_GROOVE: 02463 str = (gchar *) "border-style-groove"; 02464 break; 02465 case BORDER_STYLE_RIDGE: 02466 str = (gchar *) "border-style-ridge"; 02467 break; 02468 case BORDER_STYLE_INSET: 02469 str = (gchar *) "border-style-inset"; 02470 break; 02471 case BORDER_STYLE_OUTSET: 02472 str = (gchar *) "border-style-outset"; 02473 break; 02474 default: 02475 str = (gchar *) "unknown border style"; 02476 break; 02477 } 02478 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); 02479 g_string_append (a_str, str); 02480 return CR_OK; 02481 } 02482 02483 enum CRStatus 02484 cr_style_display_type_to_string (enum CRDisplayType a_code, 02485 GString * a_str, guint a_nb_indent) 02486 { 02487 gchar *str = NULL; 02488 02489 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); 02490 02491 switch (a_code) { 02492 case DISPLAY_NONE: 02493 str = (gchar *) "display-none"; 02494 break; 02495 case DISPLAY_INLINE: 02496 str = (gchar *) "display-inline"; 02497 break; 02498 case DISPLAY_BLOCK: 02499 str = (gchar *) "display-block"; 02500 break; 02501 case DISPLAY_LIST_ITEM: 02502 str = (gchar *) "display-list-item"; 02503 break; 02504 case DISPLAY_RUN_IN: 02505 str = (gchar *) "display-run-in"; 02506 break; 02507 case DISPLAY_COMPACT: 02508 str = (gchar *) "display-compact"; 02509 break; 02510 case DISPLAY_MARKER: 02511 str = (gchar *) "display-marker"; 02512 break; 02513 case DISPLAY_TABLE: 02514 str = (gchar *) "display-table"; 02515 break; 02516 case DISPLAY_INLINE_TABLE: 02517 str = (gchar *) "display-inline-table"; 02518 break; 02519 case DISPLAY_TABLE_ROW_GROUP: 02520 str = (gchar *) "display-table-row-group"; 02521 break; 02522 case DISPLAY_TABLE_HEADER_GROUP: 02523 str = (gchar *) "display-table-header-group"; 02524 break; 02525 case DISPLAY_TABLE_FOOTER_GROUP: 02526 str = (gchar *) "display-table-footer-group"; 02527 break; 02528 case DISPLAY_TABLE_ROW: 02529 str = (gchar *) "display-table-row"; 02530 break; 02531 case DISPLAY_TABLE_COLUMN_GROUP: 02532 str = (gchar *) "display-table-column-group"; 02533 break; 02534 case DISPLAY_TABLE_COLUMN: 02535 str = (gchar *) "display-table-column"; 02536 break; 02537 case DISPLAY_TABLE_CELL: 02538 str = (gchar *) "display-table-cell"; 02539 break; 02540 case DISPLAY_TABLE_CAPTION: 02541 str = (gchar *) "display-table-caption"; 02542 break; 02543 case DISPLAY_INHERIT: 02544 str = (gchar *) "display-inherit"; 02545 break; 02546 default: 02547 str = (gchar *) "unknown display property"; 02548 break; 02549 } 02550 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); 02551 g_string_append (a_str, str); 02552 return CR_OK; 02553 02554 } 02555 02556 enum CRStatus 02557 cr_style_position_type_to_string (enum CRPositionType a_code, 02558 GString * a_str, guint a_nb_indent) 02559 { 02560 gchar *str = NULL; 02561 02562 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); 02563 02564 switch (a_code) { 02565 case POSITION_STATIC: 02566 str = (gchar *) "position-static"; 02567 break; 02568 case POSITION_RELATIVE: 02569 str = (gchar *) "position-relative"; 02570 break; 02571 case POSITION_ABSOLUTE: 02572 str = (gchar *) "position-absolute"; 02573 break; 02574 case POSITION_FIXED: 02575 str = (gchar *) "position-fixed"; 02576 break; 02577 case POSITION_INHERIT: 02578 str = (gchar *) "position-inherit"; 02579 break; 02580 default: 02581 str = (gchar *) "unknown static property"; 02582 } 02583 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); 02584 g_string_append (a_str, str); 02585 return CR_OK; 02586 } 02587 02588 enum CRStatus 02589 cr_style_float_type_to_string (enum CRFloatType a_code, 02590 GString * a_str, guint a_nb_indent) 02591 { 02592 gchar *str = NULL; 02593 02594 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); 02595 02596 switch (a_code) { 02597 case FLOAT_NONE: 02598 str = (gchar *) "float-none"; 02599 break; 02600 case FLOAT_LEFT: 02601 str = (gchar *) "float-left"; 02602 break; 02603 case FLOAT_RIGHT: 02604 str = (gchar *) "float-right"; 02605 break; 02606 case FLOAT_INHERIT: 02607 str = (gchar *) "float-inherit"; 02608 break; 02609 default: 02610 str = (gchar *) "unknown float property value"; 02611 break; 02612 } 02613 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); 02614 g_string_append (a_str, str); 02615 return CR_OK; 02616 } 02617 02618 enum CRStatus 02619 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code, 02620 GString * a_str, guint a_nb_indent) 02621 { 02622 gchar *str = NULL; 02623 02624 g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); 02625 02626 switch (a_code) { 02627 case WHITE_SPACE_NORMAL: 02628 str = (gchar *) "normal"; 02629 break; 02630 case WHITE_SPACE_PRE: 02631 str = (gchar *) "pre"; 02632 break; 02633 case WHITE_SPACE_NOWRAP: 02634 str = (gchar *) "nowrap"; 02635 break; 02636 case WHITE_SPACE_INHERIT: 02637 str = (gchar *) "inherited"; 02638 break; 02639 default: 02640 str = (gchar *) "unknown white space property value"; 02641 break; 02642 } 02643 cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); 02644 g_string_append (a_str, str); 02645 return CR_OK; 02646 } 02647 02648 /** 02649 *Serializes in instance of #CRStyle into 02650 *a string 02651 *@param a_this the instance of #CRStyle to serialize 02652 *@param a_str the string to serialise the style into. 02653 *if *a_str is NULL, a new GString is instanciated, otherwise 02654 *the style serialisation is appended to the existed *a_str 02655 *@param the number of white space char to use for indentation. 02656 *@return CR_OK upon successful completion, an error code otherwise. 02657 */ 02658 enum CRStatus 02659 cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) 02660 { 02661 const gint INTERNAL_INDENT = 2; 02662 gint indent = a_nb_indent + INTERNAL_INDENT; 02663 gchar *tmp_str = NULL; 02664 GString *str = NULL; 02665 gint i = 0; 02666 02667 g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR); 02668 02669 if (!*a_str) { 02670 str = g_string_new (NULL); 02671 } else { 02672 str = *a_str; 02673 } 02674 cr_utils_dump_n_chars2 (' ', str, a_nb_indent); 02675 g_string_append (str, "style {\n"); 02676 02677 /*loop over the num_props and to_string() them */ 02678 for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) { 02679 /* 02680 *to_string() the name of the num_prop 02681 *(using num_prop_code_to_string) 02682 *before outputing it value 02683 */ 02684 cr_utils_dump_n_chars2 (' ', str, indent); 02685 tmp_str = (gchar *) num_prop_code_to_string (i); 02686 if (tmp_str) { 02687 g_string_append_printf (str, "%s: ", tmp_str); 02688 } else { 02689 g_string_append (str, "NULL"); 02690 } 02691 tmp_str = NULL; 02692 cr_style_num_prop_val_to_string (&a_this->num_props[i], str, 02693 a_nb_indent + 02694 INTERNAL_INDENT); 02695 g_string_append (str, "\n"); 02696 } 02697 /*loop over the rgb_props and to_string() them all */ 02698 for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) { 02699 tmp_str = (gchar *) rgb_prop_code_to_string (i); 02700 cr_utils_dump_n_chars2 (' ', str, indent); 02701 if (tmp_str) { 02702 g_string_append_printf (str, "%s: ", tmp_str); 02703 } else { 02704 g_string_append (str, "NULL: "); 02705 } 02706 tmp_str = NULL; 02707 cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str, 02708 a_nb_indent + 02709 INTERNAL_INDENT); 02710 g_string_append (str, "\n"); 02711 } 02712 /*loop over the border_style_props and to_string() them */ 02713 for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) { 02714 tmp_str = (gchar *) border_style_prop_code_to_string (i); 02715 cr_utils_dump_n_chars2 (' ', str, indent); 02716 if (tmp_str) { 02717 g_string_append_printf (str, "%s: ", tmp_str); 02718 } else { 02719 g_string_append (str, "NULL: "); 02720 } 02721 tmp_str = NULL; 02722 cr_style_border_style_to_string (a_this-> 02723 border_style_props[i], str, 02724 0); 02725 g_string_append (str, "\n"); 02726 } 02727 cr_utils_dump_n_chars2 (' ', str, indent); 02728 g_string_append (str, "display: "); 02729 cr_style_display_type_to_string (a_this->display, str, 0); 02730 g_string_append (str, "\n"); 02731 02732 cr_utils_dump_n_chars2 (' ', str, indent); 02733 g_string_append (str, "position: "); 02734 cr_style_position_type_to_string (a_this->position, str, 0); 02735 g_string_append (str, "\n"); 02736 02737 cr_utils_dump_n_chars2 (' ', str, indent); 02738 g_string_append (str, "float-type: "); 02739 cr_style_float_type_to_string (a_this->float_type, str, 0); 02740 g_string_append (str, "\n"); 02741 02742 cr_utils_dump_n_chars2 (' ', str, indent); 02743 g_string_append (str, "white-space: "); 02744 cr_style_white_space_type_to_string (a_this->white_space, str, 0); 02745 g_string_append (str, "\n"); 02746 02747 cr_utils_dump_n_chars2 (' ', str, indent); 02748 g_string_append (str, "font-family: "); 02749 tmp_str = (gchar *) cr_font_family_to_string (a_this->font_family, TRUE); 02750 if (tmp_str) { 02751 g_string_append (str, tmp_str); 02752 g_free (tmp_str); 02753 tmp_str = NULL; 02754 } else { 02755 g_string_append (str, "NULL"); 02756 } 02757 g_string_append (str, "\n"); 02758 02759 cr_utils_dump_n_chars2 (' ', str, indent); 02760 tmp_str = cr_font_size_to_string (&a_this->font_size.sv); 02761 if (tmp_str) { 02762 g_string_append_printf (str, "font-size {sv:%s, ", 02763 tmp_str) ; 02764 } else { 02765 g_string_append (str, "font-size {sv:NULL, "); 02766 } 02767 tmp_str = cr_font_size_to_string (&a_this->font_size.cv); 02768 if (tmp_str) { 02769 g_string_append_printf (str, "cv:%s, ", tmp_str); 02770 } else { 02771 g_string_append (str, "cv:NULL, "); 02772 } 02773 tmp_str = cr_font_size_to_string (&a_this->font_size.av); 02774 if (tmp_str) { 02775 g_string_append_printf (str, "av:%s}", tmp_str); 02776 } else { 02777 g_string_append (str, "av:NULL}"); 02778 } 02779 02780 tmp_str = NULL; 02781 g_string_append (str, "\n"); 02782 02783 cr_utils_dump_n_chars2 (' ', str, indent); 02784 tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust); 02785 if (tmp_str) { 02786 g_string_append_printf (str, "font-size-adjust: %s", tmp_str); 02787 } else { 02788 g_string_append (str, "font-size-adjust: NULL"); 02789 } 02790 tmp_str = NULL; 02791 g_string_append (str, "\n"); 02792 02793 cr_utils_dump_n_chars2 (' ', str, indent); 02794 tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style); 02795 if (tmp_str) { 02796 g_string_append_printf (str, "font-style: %s", tmp_str); 02797 } else { 02798 g_string_append (str, "font-style: NULL"); 02799 } 02800 tmp_str = NULL; 02801 g_string_append (str, "\n"); 02802 02803 cr_utils_dump_n_chars2 (' ', str, indent); 02804 tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant); 02805 if (tmp_str) { 02806 g_string_append_printf (str, "font-variant: %s", tmp_str); 02807 } else { 02808 g_string_append (str, "font-variant: NULL"); 02809 } 02810 tmp_str = NULL; 02811 g_string_append (str, "\n"); 02812 02813 cr_utils_dump_n_chars2 (' ', str, indent); 02814 tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight); 02815 if (tmp_str) { 02816 g_string_append_printf (str, "font-weight: %s", tmp_str); 02817 } else { 02818 g_string_append (str, "font-weight: NULL"); 02819 } 02820 tmp_str = NULL; 02821 g_string_append (str, "\n"); 02822 02823 cr_utils_dump_n_chars2 (' ', str, indent); 02824 tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch); 02825 if (tmp_str) { 02826 g_string_append_printf (str, "font-stretch: %s", tmp_str); 02827 } else { 02828 g_string_append (str, "font-stretch: NULL"); 02829 } 02830 tmp_str = NULL; 02831 g_string_append (str, "\n"); 02832 02833 02834 cr_utils_dump_n_chars2 (' ', str, a_nb_indent); 02835 g_string_append (str, "}"); 02836 02837 return CR_OK; 02838 } 02839 02840 /** 02841 *Destructor of the #CRStyle class. 02842 *@param a_this the instance to destroy. 02843 */ 02844 void 02845 cr_style_destroy (CRStyle * a_this) 02846 { 02847 g_return_if_fail (a_this); 02848 02849 g_free (a_this); 02850 } 02851