/cssed-0.4.0/libcroco/parser/cr-style.c
C | 2851 lines | 2260 code | 387 blank | 204 comment | 487 complexity | 06c6bad09f7687ac494c1b3febb81d02 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
- /*
- * This file is part of The Croco Library
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2.1 of
- * the GNU Lesser General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the
- * GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- *
- * Author: Dodji Seketeli.
- * see COPYRIGTHS file for copyright information
- */
- #include <string.h>
- #include "cr-style.h"
- /**
- *@file
- *The definition of the #CRStyle class.
- */
- /**
- *A property ID.
- *Each supported css property has an ID which is
- *an entry into a property "population" jump table.
- *each entry of the property population jump table
- *contains code to tranform the literal form of
- *a property value into a strongly typed value.
- */
- enum CRPropertyID {
- PROP_ID_NOT_KNOWN = 0,
- PROP_ID_PADDING_TOP,
- PROP_ID_PADDING_RIGHT,
- PROP_ID_PADDING_BOTTOM,
- PROP_ID_PADDING_LEFT,
- PROP_ID_PADDING,
- PROP_ID_BORDER_TOP_WIDTH,
- PROP_ID_BORDER_RIGHT_WIDTH,
- PROP_ID_BORDER_BOTTOM_WIDTH,
- PROP_ID_BORDER_LEFT_WIDTH,
- PROP_ID_BORDER_WIDTH,
- PROP_ID_BORDER_TOP_STYLE,
- PROP_ID_BORDER_RIGHT_STYLE,
- PROP_ID_BORDER_BOTTOM_STYLE,
- PROP_ID_BORDER_LEFT_STYLE,
- PROP_ID_BORDER_STYLE,
- PROP_ID_BORDER_TOP_COLOR,
- PROP_ID_BORDER_RIGHT_COLOR,
- PROP_ID_BORDER_BOTTOM_COLOR,
- PROP_ID_BORDER_LEFT_COLOR,
- PROP_ID_BORDER_TOP,
- PROP_ID_BORDER_RIGHT,
- PROP_ID_BORDER_BOTTOM,
- PROP_ID_BORDER_LEFT,
- PROP_ID_BORDER,
- PROP_ID_MARGIN_TOP,
- PROP_ID_MARGIN_RIGHT,
- PROP_ID_MARGIN_BOTTOM,
- PROP_ID_MARGIN_LEFT,
- PROP_ID_MARGIN,
- PROP_ID_DISPLAY,
- PROP_ID_POSITION,
- PROP_ID_TOP,
- PROP_ID_RIGHT,
- PROP_ID_BOTTOM,
- PROP_ID_LEFT,
- PROP_ID_FLOAT,
- PROP_ID_WIDTH,
- PROP_ID_COLOR,
- PROP_ID_BACKGROUND_COLOR,
- PROP_ID_FONT_FAMILY,
- PROP_ID_FONT_SIZE,
- PROP_ID_FONT_STYLE,
- PROP_ID_FONT_WEIGHT,
- PROP_ID_WHITE_SPACE,
- /*should be the last one. */
- NB_PROP_IDS
- };
- typedef struct _CRPropertyDesc CRPropertyDesc;
- struct _CRPropertyDesc {
- const guchar *name;
- enum CRPropertyID prop_id;
- };
- static CRPropertyDesc gv_prop_table[] = {
- {"padding-top", PROP_ID_PADDING_TOP},
- {"padding-right", PROP_ID_PADDING_RIGHT},
- {"padding-bottom", PROP_ID_PADDING_BOTTOM},
- {"padding-left", PROP_ID_PADDING_LEFT},
- {"padding", PROP_ID_PADDING},
- {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
- {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
- {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
- {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
- {"border-width", PROP_ID_BORDER_WIDTH},
- {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
- {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
- {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
- {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
- {"border-style", PROP_ID_BORDER_STYLE},
- {"border-top", PROP_ID_BORDER_TOP},
- {"border-right", PROP_ID_BORDER_RIGHT},
- {"border-bottom", PROP_ID_BORDER_BOTTOM},
- {"border-left", PROP_ID_BORDER_LEFT},
- {"border", PROP_ID_BORDER},
- {"margin-top", PROP_ID_MARGIN_TOP},
- {"margin-right", PROP_ID_MARGIN_RIGHT},
- {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
- {"margin-left", PROP_ID_MARGIN_LEFT},
- {"margin", PROP_ID_MARGIN},
- {"display", PROP_ID_DISPLAY},
- {"position", PROP_ID_POSITION},
- {"top", PROP_ID_TOP},
- {"right", PROP_ID_RIGHT},
- {"bottom", PROP_ID_BOTTOM},
- {"left", PROP_ID_LEFT},
- {"float", PROP_ID_FLOAT},
- {"width", PROP_ID_WIDTH},
- {"color", PROP_ID_COLOR},
- {"border-top-color", PROP_ID_BORDER_TOP_COLOR},
- {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR},
- {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR},
- {"border-left-color", PROP_ID_BORDER_LEFT_COLOR},
- {"background-color", PROP_ID_BACKGROUND_COLOR},
- {"font-family", PROP_ID_FONT_FAMILY},
- {"font-size", PROP_ID_FONT_SIZE},
- {"font-style", PROP_ID_FONT_STYLE},
- {"font-weight", PROP_ID_FONT_WEIGHT},
- {"white-space", PROP_ID_WHITE_SPACE},
- /*must be the last one */
- {NULL, 0}
- };
- /**
- *A the key/value pair of this hash table
- *are:
- *key => name of the the css propertie found in gv_prop_table
- *value => matching property id found in gv_prop_table.
- *So this hash table is here just to retrieval of a property id
- *from a property name.
- */
- static GHashTable *gv_prop_hash = NULL;
- /**
- *incremented by each new instance of #CRStyle
- *and decremented at the it destroy time.
- *When this reaches zero, gv_prop_hash is destroyed.
- */
- static gulong gv_prop_hash_ref_count = 0;
- struct CRNumPropEnumDumpInfo {
- enum CRNumProp code;
- const gchar *str;
- };
- static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
- {NUM_PROP_TOP, "top"},
- {NUM_PROP_RIGHT, "right"},
- {NUM_PROP_BOTTOM, "bottom"},
- {NUM_PROP_LEFT, "left"},
- {NUM_PROP_PADDING_TOP, "padding-top"},
- {NUM_PROP_PADDING_RIGHT, "padding-right"},
- {NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
- {NUM_PROP_PADDING_LEFT, "padding-left"},
- {NUM_PROP_BORDER_TOP, "border-top"},
- {NUM_PROP_BORDER_RIGHT, "border-right"},
- {NUM_PROP_BORDER_BOTTOM, "border-bottom"},
- {NUM_PROP_BORDER_LEFT, "border-left"},
- {NUM_PROP_MARGIN_TOP, "margin-top"},
- {NUM_PROP_MARGIN_RIGHT, "margin-right"},
- {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
- {NUM_PROP_MARGIN_LEFT, "margin-left"},
- {NUM_PROP_WIDTH, "width"},
- {0, NULL}
- };
- struct CRRgbPropEnumDumpInfo {
- enum CRRgbProp code;
- const gchar *str;
- };
- static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
- {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
- {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
- {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
- {RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
- {RGB_PROP_COLOR, "color"},
- {RGB_PROP_BACKGROUND_COLOR, "background-color"},
- {0, NULL}
- };
- struct CRBorderStylePropEnumDumpInfo {
- enum CRBorderStyleProp code;
- const gchar *str;
- };
- static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
- = {
- {BORDER_STYLE_PROP_TOP, "border-style-top"},
- {BORDER_STYLE_PROP_RIGHT, "border-style-right"},
- {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
- {BORDER_STYLE_PROP_LEFT, "border-style-left"},
- {0, NULL}
- };
- static enum CRStatus
- cr_style_init_properties (void);
- enum CRDirection {
- DIR_TOP = 0,
- DIR_RIGHT,
- DIR_BOTTOM,
- DIR_LEFT,
- /*must be the last one */
- NB_DIRS
- };
- static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
- static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
- static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
- a_code);
- static enum CRStatus
- set_prop_padding_x_from_value (CRStyle * a_style,
- CRTerm * a_value, enum CRDirection a_dir);
- static enum CRStatus
- set_prop_border_x_width_from_value (CRStyle * a_style,
- CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_border_width_from_value (CRStyle *a_style,
- CRTerm *a_value) ;
- static enum CRStatus
- set_prop_border_x_style_from_value (CRStyle * a_style,
- CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_border_style_from_value (CRStyle *a_style,
- CRTerm *a_value) ;
- static enum CRStatus
- set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_float (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_width (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_color (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir);
- static enum CRStatus
- set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- init_style_font_size_field (CRStyle * a_style);
- static enum CRStatus
- set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
- static enum CRStatus
- set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
- static const gchar *
- num_prop_code_to_string (enum CRNumProp a_code)
- {
- gint len = sizeof (gv_num_props_dump_infos) /
- sizeof (struct CRNumPropEnumDumpInfo);
- if (a_code >= len) {
- cr_utils_trace_info ("A field has been added "
- "to 'enum CRNumProp' and no matching"
- " entry has been "
- "added to gv_num_prop_dump_infos table.\n"
- "Please add the missing matching entry");
- return NULL;
- }
- if (gv_num_props_dump_infos[a_code].code != a_code) {
- cr_utils_trace_info ("mismatch between the order of fields in"
- " 'enum CRNumProp' and "
- "the order of entries in "
- "the gv_num_prop_dump_infos table");
- return NULL;
- }
- return gv_num_props_dump_infos[a_code].str;
- }
- static const gchar *
- rgb_prop_code_to_string (enum CRRgbProp a_code)
- {
- gint len = sizeof (gv_rgb_props_dump_infos) /
- sizeof (struct CRRgbPropEnumDumpInfo);
- if (a_code >= len) {
- cr_utils_trace_info ("A field has been added "
- "to 'enum CRRgbProp' and no matching"
- " entry has been "
- "added to gv_rgb_prop_dump_infos table.\n"
- "Please add the missing matching entry");
- return NULL;
- }
- if (gv_rgb_props_dump_infos[a_code].code != a_code) {
- cr_utils_trace_info ("mismatch between the order of fields in"
- " 'enum CRRgbProp' and "
- "the order of entries in "
- "the gv_rgb_props_dump_infos table");
- return NULL;
- }
- return gv_rgb_props_dump_infos[a_code].str;
- }
- static const gchar *
- border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
- {
- gint len = sizeof (gv_border_style_props_dump_infos) /
- sizeof (struct CRBorderStylePropEnumDumpInfo);
- if (a_code >= len) {
- cr_utils_trace_info ("A field has been added "
- "to 'enum CRBorderStyleProp' and no matching"
- " entry has been "
- "added to gv_border_style_prop_dump_infos table.\n"
- "Please add the missing matching entry");
- return NULL;
- }
- if (gv_border_style_props_dump_infos[a_code].code != a_code) {
- cr_utils_trace_info ("mismatch between the order of fields in"
- " 'enum CRBorderStyleProp' and "
- "the order of entries in "
- "the gv_border_style_props_dump_infos table");
- return NULL;
- }
- return gv_border_style_props_dump_infos[a_code].str;
- }
- static enum CRStatus
- cr_style_init_properties (void)
- {
- if (!gv_prop_hash) {
- gulong i = 0;
- gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal);
- if (!gv_prop_hash) {
- cr_utils_trace_info ("Out of memory");
- return CR_ERROR;
- }
- /*load gv_prop_hash from gv_prop_table */
- for (i = 0; gv_prop_table[i].name; i++) {
- g_hash_table_insert
- (gv_prop_hash,
- (gpointer) gv_prop_table[i].name,
- GINT_TO_POINTER (gv_prop_table[i].prop_id));
- }
- }
- return CR_OK;
- }
- static enum CRPropertyID
- cr_style_get_prop_id (const guchar * a_prop)
- {
- gpointer *raw_id = NULL;
- if (!gv_prop_hash) {
- cr_style_init_properties ();
- }
- raw_id = g_hash_table_lookup (gv_prop_hash, a_prop);
- if (!raw_id) {
- return PROP_ID_NOT_KNOWN;
- }
- return GPOINTER_TO_INT (raw_id);
- }
- static enum CRStatus
- set_prop_padding_x_from_value (CRStyle * a_style,
- CRTerm * a_value, enum CRDirection a_dir)
- {
- enum CRStatus status = CR_OK;
- CRNum *num_val = NULL;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
- return CR_BAD_PARAM_ERROR;
- switch (a_dir) {
- case DIR_TOP:
- num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
- break;
- case DIR_RIGHT:
- num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
- break;
- case DIR_BOTTOM:
- num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
- break;
- case DIR_LEFT:
- num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
- break;
- default:
- return CR_BAD_PARAM_ERROR;
- }
- if (a_value->type == TERM_IDENT) {
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str
- && !strncmp ((guchar *) "inherit",
- a_value->content.str->stryng->str,
- sizeof ("inherit")-1)) {
- status = cr_num_set (num_val, 0.0, NUM_INHERIT);
- return CR_OK;
- } else
- return CR_UNKNOWN_TYPE_ERROR;
- }
- g_return_val_if_fail (a_value->type == TERM_NUMBER
- && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
- switch (a_value->content.num->type) {
- case NUM_LENGTH_EM:
- case NUM_LENGTH_EX:
- case NUM_LENGTH_PX:
- case NUM_LENGTH_IN:
- case NUM_LENGTH_CM:
- case NUM_LENGTH_MM:
- case NUM_LENGTH_PT:
- case NUM_LENGTH_PC:
- case NUM_PERCENTAGE:
- status = cr_num_copy (num_val, a_value->content.num);
- break;
- default:
- status = CR_UNKNOWN_TYPE_ERROR;
- break;
- }
- return status;
- }
- static enum CRStatus
- set_prop_border_x_width_from_value (CRStyle * a_style,
- CRTerm * a_value,
- enum CRDirection a_dir)
- {
- enum CRStatus status = CR_OK;
- CRNum *num_val = NULL;
- g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
- switch (a_dir) {
- case DIR_TOP:
- num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
- break;
- case DIR_RIGHT:
- num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
- break;
- case DIR_BOTTOM:
- num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
- break;
- case DIR_LEFT:
- num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
- break;
- default:
- return CR_BAD_PARAM_ERROR;
- break;
- }
- if (a_value->type == TERM_IDENT) {
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str) {
- if (!strncmp ("thin",
- a_value->content.str->stryng->str,
- sizeof ("thin")-1)) {
- cr_num_set (num_val, BORDER_THIN,
- NUM_LENGTH_PX);
- } else if (!strncmp
- ("medium",
- a_value->content.str->stryng->str,
- sizeof ("medium")-1)) {
- cr_num_set (num_val, BORDER_MEDIUM,
- NUM_LENGTH_PX);
- } else if (!strncmp ("thick",
- a_value->content.str->stryng->str,
- sizeof ("thick")-1)) {
- cr_num_set (num_val, BORDER_THICK,
- NUM_LENGTH_PX);
- } else {
- return CR_UNKNOWN_TYPE_ERROR;
- }
- }
- } else if (a_value->type == TERM_NUMBER) {
- if (a_value->content.num) {
- cr_num_copy (num_val, a_value->content.num);
- }
- } else if (a_value->type != TERM_NUMBER
- || a_value->content.num == NULL) {
- return CR_UNKNOWN_TYPE_ERROR;
- }
- return status;
- }
- static enum CRStatus
- set_prop_border_width_from_value (CRStyle *a_style,
- CRTerm *a_value)
- {
- CRTerm *cur_term = NULL ;
- enum CRDirection direction = DIR_TOP ;
- g_return_val_if_fail (a_style && a_value,
- CR_BAD_PARAM_ERROR) ;
- cur_term = a_value ;
- if (!cur_term)
- return CR_ERROR ;
- for (direction = DIR_TOP ;
- direction < NB_DIRS ; direction ++) {
- set_prop_border_x_width_from_value (a_style,
- cur_term,
- direction) ;
- }
- cur_term = cur_term->next ;
- if (!cur_term)
- return CR_OK ;
- set_prop_border_x_width_from_value (a_style, cur_term,
- DIR_RIGHT) ;
- set_prop_border_x_width_from_value (a_style, cur_term,
- DIR_LEFT) ;
- cur_term = cur_term->next ;
- if (!cur_term)
- return CR_OK ;
- set_prop_border_x_width_from_value (a_style, cur_term,
- DIR_BOTTOM) ;
- cur_term = cur_term->next ;
- if (!cur_term)
- return CR_OK ;
- set_prop_border_x_width_from_value (a_style, cur_term,
- DIR_LEFT) ;
- return CR_OK ;
- }
- static enum CRStatus
- set_prop_border_x_style_from_value (CRStyle * a_style,
- CRTerm * a_value, enum CRDirection a_dir)
- {
- enum CRStatus status = CR_OK;
- enum CRBorderStyle *border_style_ptr = NULL;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- switch (a_dir) {
- case DIR_TOP:
- border_style_ptr = &a_style->
- border_style_props[BORDER_STYLE_PROP_TOP];
- break;
- case DIR_RIGHT:
- border_style_ptr =
- &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
- break;
- case DIR_BOTTOM:
- border_style_ptr = &a_style->
- border_style_props[BORDER_STYLE_PROP_BOTTOM];
- break;
- case DIR_LEFT:
- border_style_ptr = &a_style->
- border_style_props[BORDER_STYLE_PROP_LEFT];
- break;
- default:
- break;
- }
- if (a_value->type != TERM_IDENT || !a_value->content.str) {
- return CR_UNKNOWN_TYPE_ERROR;
- }
- if (!strncmp ("none",
- a_value->content.str->stryng->str,
- sizeof ("none")-1)) {
- *border_style_ptr = BORDER_STYLE_NONE;
- } else if (!strncmp ("hidden",
- a_value->content.str->stryng->str,
- sizeof ("hidden")-1)) {
- *border_style_ptr = BORDER_STYLE_HIDDEN;
- } else if (!strncmp ("dotted",
- a_value->content.str->stryng->str,
- sizeof ("dotted")-1)) {
- *border_style_ptr = BORDER_STYLE_DOTTED;
- } else if (!strncmp ("dashed",
- a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
- *border_style_ptr = BORDER_STYLE_DASHED;
- } else if (!strncmp ("solid",
- a_value->content.str->stryng->str, sizeof ("solid")-1)) {
- *border_style_ptr = BORDER_STYLE_SOLID;
- } else if (!strncmp ("double",
- a_value->content.str->stryng->str, sizeof ("double")-1)) {
- *border_style_ptr = BORDER_STYLE_DOUBLE;
- } else if (!strncmp ("groove",
- a_value->content.str->stryng->str, sizeof ("groove")-1)) {
- *border_style_ptr = BORDER_STYLE_GROOVE;
- } else if (!strncmp ("ridge",
- a_value->content.str->stryng->str,
- sizeof ("ridge")-1)) {
- *border_style_ptr = BORDER_STYLE_RIDGE;
- } else if (!strncmp ("inset",
- a_value->content.str->stryng->str,
- sizeof ("inset")-1)) {
- *border_style_ptr = BORDER_STYLE_INSET;
- } else if (!strncmp ("outset",
- a_value->content.str->stryng->str,
- sizeof ("outset")-1)) {
- *border_style_ptr = BORDER_STYLE_OUTSET;
- } else if (!strncmp ("inherit",
- a_value->content.str->stryng->str,
- sizeof ("inherit")-1)) {
- *border_style_ptr = BORDER_STYLE_INHERIT;
- } else {
- status = CR_UNKNOWN_TYPE_ERROR;
- }
- return status;
- }
- static enum CRStatus
- set_prop_border_style_from_value (CRStyle *a_style,
- CRTerm *a_value)
- {
- CRTerm *cur_term = NULL ;
- enum CRDirection direction = DIR_TOP ;
- g_return_val_if_fail (a_style && a_value,
- CR_BAD_PARAM_ERROR) ;
- cur_term = a_value ;
- if (!cur_term || cur_term->type != TERM_IDENT) {
- return CR_ERROR ;
- }
-
- for (direction = DIR_TOP ;
- direction < NB_DIRS ;
- direction ++) {
- set_prop_border_x_style_from_value (a_style,
- cur_term,
- direction) ;
- }
-
- cur_term = cur_term->next ;
- if (!cur_term || cur_term->type != TERM_IDENT) {
- return CR_OK ;
- }
-
- set_prop_border_x_style_from_value (a_style, cur_term,
- DIR_RIGHT) ;
- set_prop_border_x_style_from_value (a_style, cur_term,
- DIR_LEFT) ;
- cur_term = cur_term->next ;
- if (!cur_term || cur_term->type != TERM_IDENT) {
- return CR_OK ;
- }
- set_prop_border_x_style_from_value (a_style, cur_term,
- DIR_BOTTOM) ;
-
- cur_term = cur_term->next ;
- if (!cur_term || cur_term->type != TERM_IDENT) {
- return CR_OK ;
- }
- set_prop_border_x_style_from_value (a_style, cur_term,
- DIR_LEFT) ;
- return CR_OK ;
- }
- static enum CRStatus
- set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir)
- {
- enum CRStatus status = CR_OK;
- CRNum *num_val = NULL;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- switch (a_dir) {
- case DIR_TOP:
- num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
- break;
- case DIR_RIGHT:
- num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
- break;
- case DIR_BOTTOM:
- num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
- break;
- case DIR_LEFT:
- num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
- break;
- default:
- break;
- }
- switch (a_value->type) {
- case TERM_IDENT:
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str
- && !strcmp (a_value->content.str->stryng->str,
- "inherit")) {
- status = cr_num_set (num_val, 0.0, NUM_INHERIT);
- } else if (a_value->content.str
- && a_value->content.str->stryng
- && !strcmp (a_value->content.str->stryng->str,
- "auto")) {
- status = cr_num_set (num_val, 0.0, NUM_AUTO);
- } else {
- status = CR_UNKNOWN_TYPE_ERROR;
- }
- break ;
- case TERM_NUMBER:
- status = cr_num_copy (num_val, a_value->content.num);
- break;
- default:
- status = CR_UNKNOWN_TYPE_ERROR;
- break;
- }
- return status;
- }
- struct CRPropDisplayValPair {
- const guchar *prop_name;
- enum CRDisplayType type;
- };
- static enum CRStatus
- set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- static const struct CRPropDisplayValPair disp_vals_map[] = {
- {"none", DISPLAY_NONE},
- {"inline", DISPLAY_INLINE},
- {"block", DISPLAY_BLOCK},
- {"run-in", DISPLAY_RUN_IN},
- {"compact", DISPLAY_COMPACT},
- {"marker", DISPLAY_MARKER},
- {"table", DISPLAY_TABLE},
- {"inline-table", DISPLAY_INLINE_TABLE},
- {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
- {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
- {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
- {"table-row", DISPLAY_TABLE_ROW},
- {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
- {"table-column", DISPLAY_TABLE_COLUMN},
- {"table-cell", DISPLAY_TABLE_CELL},
- {"table-caption", DISPLAY_TABLE_CAPTION},
- {"inherit", DISPLAY_INHERIT},
- {NULL, DISPLAY_NONE}
- };
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- switch (a_value->type) {
- case TERM_IDENT:
- {
- int i = 0;
- if (!a_value->content.str
- || !a_value->content.str->stryng
- || !a_value->content.str->stryng->str)
- break;
- for (i = 0; disp_vals_map[i].prop_name; i++) {
- if (!strncmp
- (disp_vals_map[i].prop_name,
- a_value->content.str->stryng->str,
- strlen (disp_vals_map[i].prop_name))) {
- a_style->display =
- disp_vals_map[i].type;
- break;
- }
- }
- }
- break;
- default:
- break;
- }
- return CR_OK;
- }
- struct CRPropPositionValPair {
- const guchar *name;
- enum CRPositionType type;
- };
- static enum CRStatus
- set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
- static const struct CRPropPositionValPair position_vals_map[] = {
- {"static", POSITION_STATIC},
- {"relative", POSITION_RELATIVE},
- {"absolute", POSITION_ABSOLUTE},
- {"fixed", POSITION_FIXED},
- {"inherit", POSITION_INHERIT},
- {NULL, POSITION_STATIC}
- /*must alwas be the last one */
- };
- g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
- switch (a_value->type) {
- case TERM_IDENT:
- {
- int i = 0;
- if (!a_value->content.str
- || !a_value->content.str->stryng
- || !a_value->content.str->stryng->str)
- break;
- for (i = 0; position_vals_map[i].name; i++) {
- if (!strncmp (position_vals_map[i].name,
- a_value->content.str->stryng->str,
- strlen (position_vals_map[i].
- name))) {
- a_style->position =
- position_vals_map[i].type;
- status = CR_OK;
- break;
- }
- }
- }
- break;
- default:
- break;
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir)
- {
- CRNum *box_offset = NULL;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- if (!(a_value->type == TERM_NUMBER)
- && !(a_value->type == TERM_IDENT)) {
- return CR_UNKNOWN_PROP_VAL_ERROR;
- }
- switch (a_dir) {
- case DIR_TOP:
- box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
- break;
- case DIR_RIGHT:
- box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
- break;
- case DIR_BOTTOM:
- box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
- break;
- case DIR_LEFT:
- box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
- break;
- default:
- break;
- }
- box_offset->type = NUM_AUTO;
- if (a_value->type == TERM_NUMBER && a_value->content.num) {
- cr_num_copy (box_offset, a_value->content.num);
- } else if (a_value->type == TERM_IDENT
- && a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str) {
- if (!strncmp ("inherit",
- a_value->content.str->stryng->str,
- sizeof ("inherit")-1)) {
- cr_num_set (box_offset, 0.0, NUM_INHERIT);
- } else if (!strncmp ("auto",
- a_value->content.str->stryng->str,
- sizeof ("auto")-1)) {
- box_offset->type = NUM_AUTO;
- }
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_float (CRStyle * a_style, CRTerm * a_value)
- {
- g_return_val_if_fail (a_style && a_value,
- CR_BAD_PARAM_ERROR);
- /*the default float type as specified by the css2 spec */
- a_style->float_type = FLOAT_NONE;
- if (a_value->type != TERM_IDENT
- || !a_value->content.str
- || !a_value->content.str->stryng
- || !a_value->content.str->stryng->str) {
- /*unknow type, the float type is set to it's default value */
- return CR_OK;
- }
- if (!strncmp ("none",
- a_value->content.str->stryng->str,
- sizeof ("none")-1)) {
- a_style->float_type = FLOAT_NONE;
- } else if (!strncmp ("left",
- a_value->content.str->stryng->str,
- sizeof ("left")-1)) {
- a_style->float_type = FLOAT_LEFT;
- } else if (!strncmp ("right",
- a_value->content.str->stryng->str,
- sizeof ("right")-1)) {
- a_style->float_type = FLOAT_RIGHT;
- } else if (!strncmp ("inherit",
- a_value->content.str->stryng->str,
- sizeof ("inherit")-1)) {
- a_style->float_type = FLOAT_INHERIT;
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_width (CRStyle * a_style, CRTerm * a_value)
- {
- CRNum *width = NULL;
- g_return_val_if_fail (a_style
- && a_value,
- CR_BAD_PARAM_ERROR);
- width = &a_style->num_props[NUM_PROP_WIDTH].sv;
- cr_num_set (width, 0.0, NUM_AUTO);
- if (a_value->type == TERM_IDENT) {
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str) {
- if (!strncmp ("auto",
- a_value->content.str->stryng->str,
- sizeof ("auto")-1)) {
- cr_num_set (width, 0.0, NUM_AUTO);
- } else if (!strncmp ("inherit",
- a_value->content.str->stryng->str,
- sizeof ("inherit")-1)) {
- cr_num_set (width, 0.0, NUM_INHERIT);
- }
- }
- } else if (a_value->type == TERM_NUMBER) {
- if (a_value->content.num) {
- cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
- a_value->content.num);
- }
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_color (CRStyle * a_style, CRTerm * a_value)
- {
- enum CRStatus status = CR_OK;
- CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
- g_return_val_if_fail (a_style
- && a_value, CR_BAD_PARAM_ERROR);
- status = cr_rgb_set_from_term (a_rgb, a_value);
- return status;
- }
- static enum CRStatus
- set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
- {
- enum CRStatus status = CR_OK;
- CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- status = cr_rgb_set_from_term (rgb, a_value);
- return status;
- }
- /**
- *Sets border-top-color, border-right-color,
- *border-bottom-color or border-left-color properties
- *in the style structure. The value is taken from a
- *css2 term of type IDENT or RGB.
- *@param a_style the style structure to set.
- *@param a_value the css2 term to take the color information from.
- *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
- *@return CR_OK upon successfull completion, an error code otherwise.
- */
- static enum CRStatus
- set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir)
- {
- CRRgb *rgb_color = NULL;
- enum CRStatus status = CR_OK;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- switch (a_dir) {
- case DIR_TOP:
- rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
- break;
- case DIR_RIGHT:
- rgb_color =
- &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
- break;
- case DIR_BOTTOM:
- rgb_color =
- &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
- break;
- case DIR_LEFT:
- rgb_color =
- &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
- break;
- default:
- cr_utils_trace_info ("unknown DIR type");
- return CR_BAD_PARAM_ERROR;
- }
- status = CR_UNKNOWN_PROP_VAL_ERROR;
- if (a_value->type == TERM_IDENT) {
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str) {
- status = cr_rgb_set_from_name
- (rgb_color,
- a_value->content.str->stryng->str);
- }
- if (status != CR_OK) {
- cr_rgb_set_from_name (rgb_color, "black");
- }
- } else if (a_value->type == TERM_RGB) {
- if (a_value->content.rgb) {
- status = cr_rgb_set_from_rgb
- (rgb_color, a_value->content.rgb);
- }
- }
- return status;
- }
- static enum CRStatus
- set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
- enum CRDirection a_dir)
- {
- CRTerm *cur_term = NULL;
- enum CRStatus status = CR_OK;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- for (cur_term = a_value;
- cur_term;
- cur_term = cur_term->next) {
- status = set_prop_border_x_width_from_value (a_style,
- cur_term, a_dir);
- if (status != CR_OK) {
- status = set_prop_border_x_style_from_value
- (a_style, cur_term, a_dir);
- }
- if (status != CR_OK) {
- status = set_prop_border_x_color_from_value
- (a_style, cur_term, a_dir);
- }
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- enum CRDirection direction = 0;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- for (direction = 0; direction < NB_DIRS; direction++) {
- set_prop_border_x_from_value (a_style,
- a_value,
- direction);
- }
- return CR_OK;
- }
- static enum CRStatus
- set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- CRTerm *cur_term = NULL;
- enum CRDirection direction = 0;
- enum CRStatus status = CR_OK;
-
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- cur_term = a_value;
- /*filter the eventual non NUMBER terms some user can have written here*/
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_ERROR ;
- for (direction = 0; direction < NB_DIRS; direction++) {
- set_prop_padding_x_from_value (a_style, cur_term, direction);
- }
- cur_term = cur_term->next;
- /*filter non NUMBER terms that some users can have written here...*/
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- /*the user can have just written padding: 1px*/
- if (!cur_term)
- return CR_OK;
- set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
- set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
- return status;
- }
- static enum CRStatus
- set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- CRTerm *cur_term = NULL;
- enum CRDirection direction = 0;
- enum CRStatus status = CR_OK;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- cur_term = a_value;
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- for (direction = 0; direction < NB_DIRS; direction++) {
- set_prop_margin_x_from_value (a_style, cur_term, direction);
- }
- cur_term = cur_term->next;
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
- set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
- while (cur_term && cur_term->type != TERM_NUMBER) {
- cur_term = cur_term->next;
- }
- if (!cur_term)
- return CR_OK;
- status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
- return status;
- }
- static enum CRStatus
- set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- CRTerm *cur_term = NULL;
- CRFontFamily *font_family = NULL,
- *cur_ff = NULL,
- *cur_ff2 = NULL;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- if (a_value->type == TERM_IDENT &&
- a_value->content.str &&
- a_value->content.str->stryng &&
- a_value->content.str->stryng->str &&
- !strcmp ("inherit", a_value->content.str->stryng->str))
- {
- font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
- goto out;
- }
- for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
- switch (cur_term->type) {
- case TERM_IDENT:
- {
- enum CRFontFamilyType font_type;
- if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str
- && !strcmp
- (cur_term->content.str->stryng->str,
- "sans-serif")) {
- font_type = FONT_FAMILY_SANS_SERIF;
- } else if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str
- && !strcmp
- (cur_term->content.str->stryng->str,
- "serif")) {
- font_type = FONT_FAMILY_SERIF;
- } else if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str
- && !strcmp (cur_term->content.str->stryng->str,
- "cursive")) {
- font_type = FONT_FAMILY_CURSIVE;
- } else if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str
- && !strcmp (cur_term->content.str->stryng->str,
- "fantasy")) {
- font_type = FONT_FAMILY_FANTASY;
- } else if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str
- && !strcmp (cur_term->content.str->stryng->str,
- "monospace")) {
- font_type = FONT_FAMILY_MONOSPACE;
- } else {
- /*
- *unknown property value.
- *ignore it.
- */
- continue;
- }
- cur_ff = cr_font_family_new (font_type, NULL);
- }
- break;
- case TERM_STRING:
- {
- if (cur_term->content.str
- && cur_term->content.str->stryng
- && cur_term->content.str->stryng->str) {
- cur_ff = cr_font_family_new
- (FONT_FAMILY_NON_GENERIC,
- cur_term->content.str->stryng->str);
- }
- }
- break;
- default:
- break;
- }
- cur_ff2 = cr_font_family_append (font_family, cur_ff);
- if (cur_ff2) {
- font_family = cur_ff2;
- }
- }
- out:
- if (font_family) {
- if (a_style->font_family) {
- cr_font_family_destroy (a_style->font_family);
- a_style->font_family = NULL ;
- }
- a_style->font_family = font_family;
- font_family = NULL ;
- }
- return CR_OK;
- }
- static enum CRStatus
- init_style_font_size_field (CRStyle * a_style)
- {
- g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
- memset (&a_style->font_size, 0,
- sizeof (CRFontSizeVal)) ;
- /*
- if (!a_style->font_size) {
- a_style->font_size = cr_font_size_new ();
- if (!a_style->font_size) {
- return CR_INSTANCIATION_FAILED_ERROR;
- }
- } else {
- cr_font_size_clear (a_style->font_size);
- }
- */
- return CR_OK;
- }
- static enum CRStatus
- set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
- {
- enum CRStatus status = CR_OK;
- g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
- switch (a_value->type) {
- case TERM_IDENT:
- if (a_value->content.str
- && a_value->content.str->stryng
- && a_value->content.str->stryng->str
- && !strcmp (a_value->content.str->…
Large files files are truncated, but you can click here to view the full file