diff options
author | Dodji Seketeli <dodji@gnome.org> | 2004-01-24 19:24:08 +0000 |
---|---|---|
committer | Dodji Seketeli <dodji@src.gnome.org> | 2004-01-24 19:24:08 +0000 |
commit | d058779c836ec6ac56721581dd44d1dd91d3206c (patch) | |
tree | f371ad9e5150f3526edd528e44f990e9d060014c /src/cr-style.c | |
parent | a97a943a32d37e1c92aa93e861a28d96f84f2163 (diff) | |
download | libcroco-d058779c836ec6ac56721581dd44d1dd91d3206c.tar.gz |
separated the library into two projects. Libcroco is now the combination
2004-01-24 Dodji Seketeli <dodji@gnome.org>
* all: separated the library into two projects. Libcroco
is now the combination of the parser and the selection engine.
A new project is born: sewfox. It is basically the
xml rendering/layout engine.
Libcroco now needs libxml2 and glib only.
Sewfox need libgnomecanvas2.
Diffstat (limited to 'src/cr-style.c')
-rw-r--r-- | src/cr-style.c | 2190 |
1 files changed, 2190 insertions, 0 deletions
diff --git a/src/cr-style.c b/src/cr-style.c new file mode 100644 index 0000000..8059bcd --- /dev/null +++ b/src/cr-style.c @@ -0,0 +1,2190 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org> + * + * 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 + */ + +/* + *$Id$ + */ +#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_TOP_STYLE, + PROP_ID_BORDER_RIGHT_STYLE, + PROP_ID_BORDER_BOTTOM_STYLE, + PROP_ID_BORDER_LEFT_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, + /*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-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-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}, + {"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}, + /*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 ; + +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 enum CRStatus +cr_style_set_props_to_defaults (CRStyle *a_this) ; + +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_x_style_from_value (CRStyle *a_style, + CRTerm *a_value, + enum CRDirection a_dir) ; + +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_rgb (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 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 ; +} + +/** + *Sets the style properties to their default values + *according to the css2 spec. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_style_set_props_to_defaults (CRStyle *a_this) +{ + glong i = 0 ; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + for (i = 0 ; i < NB_NUM_PROPS ; i++) + { + switch (i) + { + case NUM_PROP_WIDTH: + case NUM_PROP_TOP: + case NUM_PROP_RIGHT: + case NUM_PROP_BOTTOM: + case NUM_PROP_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_AUTO) ; + break ; + + case NUM_PROP_PADDING_TOP: + case NUM_PROP_PADDING_RIGHT: + case NUM_PROP_PADDING_BOTTOM: + case NUM_PROP_PADDING_LEFT: + case NUM_PROP_BORDER_TOP: + case NUM_PROP_BORDER_RIGHT: + case NUM_PROP_BORDER_BOTTOM: + case NUM_PROP_BORDER_LEFT: + case NUM_PROP_MARGIN_TOP: + case NUM_PROP_MARGIN_RIGHT: + case NUM_PROP_MARGIN_BOTTOM: + case NUM_PROP_MARGIN_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_LENGTH_PX) ; + break ; + + default: + cr_utils_trace_info ("Unknown property") ; + break ; + } + } + + for (i = 0 ; i < NB_RGB_PROPS ; i++) + { + + switch (i) + { + /*default foreground color is black*/ + case RGB_PROP_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, + FALSE) ; + break ; + + /*default background color is white*/ + case RGB_PROP_BACKGROUND_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, + 255, 255, 255, FALSE) ; + break ; + + default: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, + FALSE) ; + break ; + } + } + + for (i = 0 ; i < NB_BORDER_STYLE_PROPS ; i++) + { + a_this->border_style_props[i] = BORDER_STYLE_NONE ; + } + + a_this->display = DISPLAY_BLOCK ; + a_this->position = POSITION_STATIC ; + a_this->float_type = FLOAT_NONE ; + a_this->parent_style = NULL ; + + 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, *parent_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 ; + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_PADDING_TOP].sv ; + break ; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv ; + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_PADDING_RIGHT].sv; + + num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv ; + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_PADDING_RIGHT].sv ; + break ; + + case DIR_BOTTOM: + num_val = + &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv ; + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_PADDING_BOTTOM].sv ; + break ; + + case DIR_LEFT: + num_val = & a_style->num_props[NUM_PROP_PADDING_LEFT].sv ; + parent_num_val = + &a_style->parent_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->str + && !strncmp ((guchar*)"inherited", + a_value->content.str->str, + strlen ("inherited"))) + { + cr_num_copy (num_val, parent_num_val) ; + 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->str) + { + if (!strncmp ("thin", + a_value->content.str->str, + strlen ("thin"))) + { + cr_num_set (num_val, BORDER_THIN, + NUM_LENGTH_PX) ; + } + else if (!strncmp ("medium", + a_value->content.str->str, + strlen ("medium"))) + { + cr_num_set (num_val, BORDER_MEDIUM, + NUM_LENGTH_PX) ; + } + else if (!strncmp ("thick", + a_value->content.str->str, + strlen ("thick"))) + { + 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_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, + *parent_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] ; + parent_border_style_ptr = (a_style->parent_style)? + &a_style->parent_style-> + border_style_props[BORDER_STYLE_PROP_TOP]: NULL ; + + break ; + + case DIR_RIGHT: + border_style_ptr = + &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT] ; + + parent_border_style_ptr = (a_style->parent_style)? + &a_style->parent_style-> + border_style_props[BORDER_STYLE_PROP_RIGHT] : NULL ; + break ; + + case DIR_BOTTOM: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_BOTTOM] ; + parent_border_style_ptr = (a_style->parent_style)? + &a_style->parent_style-> + border_style_props[BORDER_STYLE_PROP_BOTTOM] : NULL; + break ; + + case DIR_LEFT: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_LEFT] ; + parent_border_style_ptr = (a_style->parent_style)? + &a_style->parent_style-> + border_style_props[BORDER_STYLE_PROP_LEFT] : NULL; + 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->str, + strlen ("none"))) + { + *border_style_ptr = BORDER_STYLE_NONE ; + } + else if (!strncmp ("hidden", + a_value->content.str->str, + strlen ("hidden"))) + { + *border_style_ptr = BORDER_STYLE_HIDDEN ; + } + else if (!strncmp ("dotted", + a_value->content.str->str, + strlen ("dotted"))) + { + *border_style_ptr = BORDER_STYLE_DOTTED ; + } + else if (!strncmp ("dashed", + a_value->content.str->str, + strlen ("dashed"))) + { + *border_style_ptr = BORDER_STYLE_DASHED ; + } + else if (!strncmp ("solid", + a_value->content.str->str, + strlen ("solid"))) + { + *border_style_ptr = BORDER_STYLE_SOLID ; + } + else if (!strncmp ("double", + a_value->content.str->str, + strlen ("double"))) + { + *border_style_ptr = BORDER_STYLE_DOUBLE ; + } + else if (!strncmp ("groove", + a_value->content.str->str, + strlen ("groove"))) + { + *border_style_ptr = BORDER_STYLE_GROOVE ; + } + else if (!strncmp ("ridge", + a_value->content.str->str, + strlen ("ridge"))) + { + *border_style_ptr = BORDER_STYLE_RIDGE ; + } + else if (!strncmp ("inset", + a_value->content.str->str, + strlen ("inset"))) + { + *border_style_ptr = BORDER_STYLE_INSET ; + } + else if (!strncmp ("outset", + a_value->content.str->str, + strlen ("outset"))) + { + *border_style_ptr = BORDER_STYLE_OUTSET ; + } + else if (!strncmp ("inherit", + a_value->content.str->str, + strlen ("inherit"))) + { + if (parent_border_style_ptr) + *border_style_ptr = *parent_border_style_ptr ; + } + else + { + status = CR_UNKNOWN_TYPE_ERROR ; + } + + return status ; +} + +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, *parent_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 ; + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_MARGIN_TOP].sv ; + break ; + + case DIR_RIGHT: + num_val = + &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv ; + + parent_num_val = + &a_style->parent_style-> + num_props[NUM_PROP_MARGIN_RIGHT].sv ; + break ; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv ; + parent_num_val = + &a_style->parent_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv ; + break ; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv ; + parent_num_val = + &a_style->parent_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->str + && !strncmp (a_value->content.str->str, + "inherit", strlen ("inherit"))) + { + status = cr_num_copy (num_val, parent_num_val) ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strncmp (a_value->content.str->str, + "auto", strlen ("auto"))) + { + status = cr_num_set (num_val, 0.0, NUM_AUTO) ; + } + else + { + status = CR_UNKNOWN_TYPE_ERROR ; + } + + 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) +{ + enum CRDisplayType default_display_val = DISPLAY_INLINE ; + 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) ; + + /*Sets to its default value according to the css2 spec.*/ + a_style->display = default_display_val ; + + switch (a_value->type) + { + case TERM_IDENT: + { + int i = 0 ; + + if (!a_value->content.str || !a_value->content.str->str) + break ; + + for (i = 0; disp_vals_map[i].prop_name ; i++) + { + if (!strncmp (disp_vals_map[i].prop_name, + a_value->content.str->str, + strlen + (disp_vals_map[i].prop_name))) + { + a_style->display = disp_vals_map[i].type ; + break ; + } + } + + if (a_style->display == DISPLAY_INHERIT) + { + if (a_style->parent_style) + { + a_style->display = + a_style->parent_style->display ; + } + else + { + a_style->display = default_display_val ; + } + } + } + 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}, + {"inherited", POSITION_INHERIT}, + {NULL, POSITION_STATIC} + /*must alwas be the last one*/ + } ; + + g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR) ; + + /*set to it's default value according to the css2 spec*/ + a_style->position = POSITION_STATIC ; + + switch (a_value->type) + { + case TERM_IDENT: + { + int i = 0 ; + + if (!a_value->content.str || !a_value->content.str->str) + break ; + + for (i = 0; position_vals_map[i].name ; i++) + { + if (!strncmp (position_vals_map[i].name, + a_value->content.str->str, + strlen (position_vals_map[i].name))) + { + a_style->position = + position_vals_map[i].type ; + status = CR_OK ; + break ; + } + } + if (a_style->position == POSITION_INHERIT) + { + if (a_style->parent_style) + { + a_style->position = + a_style->parent_style->position ; + } + else + { + a_style->position = POSITION_STATIC ; + } + } + } + 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, *parent_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 ; + if (a_style->parent_style) + parent_box_offset = + &a_style->parent_style-> + num_props[NUM_PROP_TOP].sv ; + break ; + + case DIR_RIGHT: + box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv ; + if (a_style->parent_style) + parent_box_offset = &a_style->parent_style-> + num_props[NUM_PROP_RIGHT].sv ; + break ; + + case DIR_BOTTOM: + box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv ; + if (a_style->parent_style) + parent_box_offset = + &a_style->parent_style-> + num_props[NUM_PROP_BOTTOM].sv ; + break ; + case DIR_LEFT: + box_offset = &a_style->num_props[NUM_PROP_LEFT].sv ; + if (a_style->parent_style) + parent_box_offset = + &a_style->parent_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->str) + { + if (!strncmp ("inherit", + a_value->content.str->str, + strlen ("inherit"))) + { + cr_num_copy (box_offset, + parent_box_offset) ; + } + else if (!strncmp ("auto", + a_value->content.str->str, + strlen ("auto"))) + { + 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->str) + {/*unknow type, the float type is set to it's default value*/ + return CR_OK ; + } + + if (!strncmp ("none", + a_value->content.str->str, + strlen ("none"))) + { + a_style->float_type = FLOAT_NONE ; + } + else if (!strncmp ("left", + a_value->content.str->str, + strlen ("left"))) + { + a_style->float_type = FLOAT_LEFT ; + } + else if (!strncmp ("right", + a_value->content.str->str, + strlen ("right"))) + { + a_style->float_type = FLOAT_RIGHT ; + } + else if (!strncmp ("inherit", + a_value->content.str->str, + strlen ("inherit"))) + { + a_style->float_type = + a_style->parent_style->float_type ; + } + + return CR_OK ; +} + + +static enum CRStatus +set_prop_width (CRStyle *a_style, CRTerm *a_value) +{ + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ; + + + a_style->num_props[NUM_PROP_WIDTH].sv.type = NUM_AUTO ; + + if (a_value->type == TERM_IDENT) + { + if (a_value->content.str + && a_value->content.str->str) + { + if (!strncmp ("auto", + a_value->content.str->str, + strlen ("auto"))) + { + a_style->num_props[NUM_PROP_WIDTH].sv.type = + NUM_AUTO ; + } + else if (!strncmp ("inherit", + a_value->content.str->str, + strlen ("inherit"))) + { + cr_num_copy + (&a_style-> + num_props[NUM_PROP_WIDTH].sv, + &a_style->parent_style-> + num_props[NUM_PROP_WIDTH].sv) ; + } + } + } + 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_rgb (CRStyle *a_style, CRTerm *a_value) +{ + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR) ; + + if (a_value->type == TERM_RGB) + { + if (a_value->content.rgb) + { + cr_rgb_set_from_rgb + (&a_style->rgb_props[RGB_PROP_COLOR].sv, + a_value->content.rgb) ; + } + + } + + return CR_OK ; +} + +static enum CRStatus +set_prop_background_color (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_RGB: + if (a_value->content.rgb) + { + status = cr_rgb_set_from_rgb + (&a_style-> + rgb_props[RGB_PROP_BACKGROUND_COLOR].sv, + a_value->content.rgb) ; + } + break ; + + case TERM_IDENT: + status = cr_rgb_set_from_name + (&a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv, + a_value->content.str->str) ; + break ; + + case TERM_HASH: + status = cr_rgb_set_from_hex_str + (&a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv, + a_value->content.str->str) ; + break ; + + default: + status = CR_UNKNOWN_TYPE_ERROR ; + break ; + } + + 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->str) + { + status = cr_rgb_set_from_name + (rgb_color, a_value->content.str->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 ; + 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_padding_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_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) ; + + + 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->str + && ! strcmp (cur_term->content.str->str, + "sans-serif")) + { + font_type = FONT_FAMILY_SANS_SERIF ; + } + else if (cur_term->content.str + && cur_term->content.str->str + && ! strcmp (cur_term->content.str->str, + "serif")) + { + font_type = FONT_FAMILY_SERIF ; + } + else if (cur_term->content.str + && cur_term->content.str->str + && ! strcmp (cur_term->content.str->str, + "cursive")) + { + font_type = FONT_FAMILY_CURSIVE ; + } + else if (cur_term->content.str + && cur_term->content.str->str + && ! strcmp (cur_term->content.str->str, + "fantasy")) + { + font_type = FONT_FAMILY_FANTASY ; + } + else if (cur_term->content.str + && cur_term->content.str->str + && ! strcmp (cur_term->content.str->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->str) + { + cur_ff = cr_font_family_new + (FONT_FAMILY_NON_GENERIC, + cur_term->content.str->str) ; + } + } + break ; + + default: + break ; + } + + cur_ff2 = cr_font_family_append (font_family, + cur_ff) ; + if (cur_ff2) + { + font_family = cur_ff2 ; + } + } + + if (font_family) + { + if (a_style->font_family) + { + cr_font_family_destroy (a_style->font_family) ; + a_style->font_family = font_family ; + } + } + + 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) ; + + 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->str + && !strcmp (a_value->content.str->str, "xx-small")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_XX_SMALL ; + + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "x-small")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_X_SMALL ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "small")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_SMALL ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "medium")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_MEDIUM ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "large")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_LARGE ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "x-large")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_X_LARGE ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "xx-large")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, + status) ; + + a_style->font_size->type = + PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.predefined = + FONT_SIZE_XX_LARGE ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "larger")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, status) ; + + a_style->font_size->type = + RELATIVE_FONT_SIZE ; + a_style->font_size->value.relative = + FONT_SIZE_LARGER ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "smaller")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, status) ; + + a_style->font_size->type = + RELATIVE_FONT_SIZE ; + a_style->font_size->value.relative = + FONT_SIZE_SMALLER ; + } + else if (a_value->content.str + && a_value->content.str->str + && !strcmp (a_value->content.str->str, "inherit")) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, status) ; + + if (a_style->parent_style + && a_style->parent_style->font_style) + { + cr_font_size_copy + (a_style->font_size, + a_style->parent_style->font_size) ; + } + } + else + { + return CR_UNKNOWN_PROP_VAL_ERROR ; + } + break ; + + case TERM_NUMBER: + if (a_value->content.num) + { + status = init_style_font_size_field (a_style) ; + g_return_val_if_fail (status == CR_OK, status) ; + + a_style->font_size->type = ABSOLUTE_FONT_SIZE ; + a_style->font_size->value.absolute = + cr_num_dup (a_value->content.num) ; + } + break ; + + default: + return CR_UNKNOWN_PROP_VAL_ERROR ; + } + + return CR_OK ; +} + +static enum CRStatus +set_prop_font_style_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->str) + { + if (!strcmp (a_value->content.str->str, "normal")) + { + a_style->font_style = FONT_STYLE_NORMAL ; + } + else if (!strcmp (a_value->content.str->str, "italic")) + { + a_style->font_style = FONT_STYLE_ITALIC ; + } + else if (!strcmp (a_value->content.str->str, "oblique")) + { + a_style->font_style = FONT_STYLE_OBLIQUE ; + } + else if (!strcmp (a_value->content.str->str, "inherit")) + { + if (!a_style->font_style) + a_style->font_style = FONT_STYLE_NORMAL; + else + a_style->font_style = + a_style->parent_style-> + font_style ; + } + else + { + status = CR_UNKNOWN_PROP_VAL_ERROR ; + } + } + break ; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR ; + break ; + } + + return status ; +} + +static enum CRStatus +set_prop_font_weight_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->str) + { + if (!strcmp (a_value->content.str->str, + "normal")) + { + a_style->font_weight = FONT_WEIGHT_NORMAL ; + } + else if (!strcmp (a_value->content.str->str, + "bold")) + { + a_style->font_weight = FONT_WEIGHT_BOLD ; + } + else if (!strcmp (a_value->content.str->str, + "bolder")) + { + a_style->font_weight = FONT_WEIGHT_BOLDER ; + } + else if (!strcmp (a_value->content.str->str, + "lighter")) + { + a_style->font_weight = FONT_WEIGHT_LIGHTER ; + } + else + { + status = CR_UNKNOWN_PROP_VAL_ERROR ; + } + + } + break ; + + case TERM_NUMBER: + if (a_value->content.num + && (a_value->content.num->type == NUM_GENERIC + ||a_value->content.num->type == NUM_AUTO)) + { + if (a_value->content.num->val <= 150) + { + a_style->font_weight = FONT_WEIGHT_100 ; + } + else if (a_value->content.num->val <= 250) + { + a_style->font_weight = FONT_WEIGHT_200 ; + } + else if (a_value->content.num->val <= 350) + { + a_style->font_weight = FONT_WEIGHT_300 ; + } + else if (a_value->content.num->val <= 450) + { + a_style->font_weight = FONT_WEIGHT_400 ; + } + else if (a_value->content.num->val <= 550) + { + a_style->font_weight = FONT_WEIGHT_500 ; + } + else if (a_value->content.num->val <= 650) + { + a_style->font_weight = FONT_WEIGHT_600 ; + } + else if (a_value->content.num->val <= 750) + { + a_style->font_weight = FONT_WEIGHT_700 ; + } + else if (a_value->content.num->val <= 850) + { + a_style->font_weight = FONT_WEIGHT_800 ; + } + else + { + a_style->font_weight = FONT_WEIGHT_900 ; + } + } + break ; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR ; + break ; + } + + return status ; +} + +/****************** + *Public methods + ******************/ + +/** + *Default constructor of #CRStyle. + */ +CRStyle * +cr_style_new (void) +{ + CRStyle *result = NULL ; + + result = g_try_malloc (sizeof (CRStyle)) ; + if (!result) + { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + memset (result, 0, sizeof (CRStyle)) ; + gv_prop_hash_ref_count ++ ; + + /*set the style properties to their default values*/ + cr_style_set_props_to_defaults (result) ; + + return result ; +} + + +/** + *Walks through a css2 property declaration, and populated the + *according field(s) in the #CRStyle structure. + *If the properties or their value(s) are/is not known, + *sets the corresponding field(s) of #CRStyle to its/their default + *value(s) + *@param a_this the instance of #CRStyle to set. + *@param a_decl the declaration from which the #CRStyle fields are set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_style_from_decl (CRStyle *a_this, CRDeclaration *a_decl) +{ + CRTerm *value = NULL ; + enum CRStatus status = CR_OK ; + + enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN ; + + g_return_val_if_fail (a_this && a_decl + && a_decl + && a_decl->property + && a_decl->property->str, + CR_BAD_PARAM_ERROR) ; + + prop_id = cr_style_get_prop_id (a_decl->property->str) ; + + value = a_decl->value ; + switch (prop_id) + { + case PROP_ID_PADDING_TOP: + status = set_prop_padding_x_from_value + (a_this, value, DIR_TOP) ; + break ; + + case PROP_ID_PADDING_RIGHT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_RIGHT) ; + break ; + case PROP_ID_PADDING_BOTTOM: + status = set_prop_padding_x_from_value + (a_this, value, DIR_BOTTOM) ; + break ; + + case PROP_ID_PADDING_LEFT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_LEFT) ; + break ; + + case PROP_ID_PADDING: + status = set_prop_padding_from_value (a_this, value) ; + break ; + + case PROP_ID_BORDER_TOP_WIDTH: + status = + set_prop_border_x_width_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER_RIGHT_WIDTH: + status = + set_prop_border_x_width_from_value (a_this, value, + DIR_RIGHT) ; + break ; + + case PROP_ID_BORDER_BOTTOM_WIDTH: + status = + set_prop_border_x_width_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_BORDER_LEFT_WIDTH: + status = + set_prop_border_x_width_from_value (a_this, value, + DIR_LEFT) ; + break ; + + case PROP_ID_BORDER_TOP_STYLE: + status = + set_prop_border_x_style_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER_RIGHT_STYLE: + status = + set_prop_border_x_style_from_value (a_this, value, + DIR_RIGHT) ; + break ; + + case PROP_ID_BORDER_BOTTOM_STYLE: + status = + set_prop_border_x_style_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_BORDER_LEFT_STYLE: + status = + set_prop_border_x_style_from_value (a_this, value, + DIR_LEFT) ; + break ; + + case PROP_ID_BORDER_TOP_COLOR: + status = + set_prop_border_x_color_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER_RIGHT_COLOR: + status = + set_prop_border_x_color_from_value (a_this, value, + DIR_RIGHT) ; + break ; + + case PROP_ID_BORDER_BOTTOM_COLOR: + status = + set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_BORDER_LEFT_COLOR: + status = + set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_BORDER_TOP: + status = + set_prop_border_x_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER_RIGHT: + status = + set_prop_border_x_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER_BOTTOM: + status = + set_prop_border_x_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_BORDER_LEFT: + status = + set_prop_border_x_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_MARGIN_TOP: + status = + set_prop_margin_x_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_BORDER: + status = + set_prop_border_from_value (a_this, value) ; + break ; + + case PROP_ID_MARGIN_RIGHT: + status = + set_prop_margin_x_from_value (a_this, value, + DIR_RIGHT) ; + break ; + + case PROP_ID_MARGIN_BOTTOM: + status = + set_prop_margin_x_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_MARGIN_LEFT: + status = + set_prop_margin_x_from_value (a_this, value, + DIR_LEFT) ; + break ; + + case PROP_ID_MARGIN: + status = + set_prop_margin_from_value (a_this, value) ; + break ; + + case PROP_ID_DISPLAY: + status = + set_prop_display_from_value (a_this, value) ; + break ; + + case PROP_ID_POSITION: + status = set_prop_position_from_value (a_this, value) ; + break ; + + case PROP_ID_TOP: + status = set_prop_x_from_value (a_this, value, + DIR_TOP) ; + break ; + + case PROP_ID_RIGHT: + status = set_prop_x_from_value (a_this, value, + DIR_RIGHT) ; + break ; + + case PROP_ID_BOTTOM: + status = set_prop_x_from_value (a_this, value, + DIR_BOTTOM) ; + break ; + + case PROP_ID_LEFT: + status = set_prop_x_from_value (a_this, value, + DIR_LEFT) ; + break ; + + case PROP_ID_FLOAT: + status = set_prop_float (a_this, value) ; + break ; + + case PROP_ID_WIDTH: + status = set_prop_width (a_this, value) ; + break ; + + case PROP_ID_COLOR: + status = set_prop_color_rgb (a_this, value) ; + break ; + + case PROP_ID_BACKGROUND_COLOR: + status = set_prop_background_color (a_this, value) ; + break ; + + case PROP_ID_FONT_FAMILY: + status = + set_prop_font_family_from_value (a_this, value) ; + break ; + + case PROP_ID_FONT_SIZE: + status = + set_prop_font_size_from_value (a_this, value) ; + break ; + + case PROP_ID_FONT_STYLE: + status = + set_prop_font_style_from_value (a_this, value) ; + break ; + + case PROP_ID_FONT_WEIGHT: + status = + set_prop_font_weight_from_value (a_this, value) ; + break ; + + default: + return CR_UNKNOWN_TYPE_ERROR ; + + } + + return status ; +} + +/** + *Increases the reference count + *of the current instance of #CRStyle. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_style_ref (CRStyle *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + a_this->ref_count ++ ; + return CR_OK ; +} + + +/** + *Decreases the reference count of + *the current instance of #CRStyle. + *If the reference count reaches 0, the + *instance of #CRStyle is destoyed. + *@param a_this the current instance of #CRStyle. + *@return TRUE if the instance has been destroyed, FALSE + *otherwise. + */ +gboolean +cr_style_unref (CRStyle *a_this) +{ + g_return_val_if_fail (a_this, + FALSE) ; + + if (a_this->ref_count) + a_this->ref_count -- ; + + if (!a_this->ref_count) + { + cr_style_destroy (a_this) ; + return TRUE ; + } + + return FALSE ; +} + +/** + *Duplicates the current instance of #CRStyle . + *The newly created instance of #CRStyle must be + *freed using cr_style_destroy (). + *@param a_this the current instance of #CRStyle. + *@return the newly duplicated instance of #CRStyle. + */ +CRStyle * +cr_style_dup (CRStyle *a_this) +{ + CRStyle *result = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + result = cr_style_new () ; + if (!result) + { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + memcpy (result, a_this, sizeof (CRStyle)) ; + + return result ; +} + + +/** + *Destructor of the #CRStyle class. + *@param a_this the instance to destroy. + */ +void +cr_style_destroy (CRStyle *a_this) +{ + g_return_if_fail (a_this) ; + + g_free (a_this) ; +} |