summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libcroco/cr-style.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/3rdparty/libcroco/cr-style.c2852
1 files changed, 2852 insertions, 0 deletions
diff --git a/src/3rdparty/libcroco/cr-style.c b/src/3rdparty/libcroco/cr-style.c
new file mode 100644
index 0000000..9653c50
--- /dev/null
+++ b/src/3rdparty/libcroco/cr-style.c
@@ -0,0 +1,2852 @@
+/* -*- 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 COPYRIGHTS 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 transform 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 gchar *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, (enum CRPropertyID) 0}
+};
+
+/**
+ *A the key/value pair of this hash table
+ *are:
+ *key => name of the css property 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"},
+ {(enum CRNumProp) 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"},
+ {(enum CRRgbProp) 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"},
+ {(enum CRBorderStyleProp) 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)
+{
+ guint 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)
+{
+ guint 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)
+{
+ guint 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 = (gpointer *) g_hash_table_lookup (gv_prop_hash, a_prop);
+ if (!raw_id) {
+ return PROP_ID_NOT_KNOWN;
+ }
+ return (enum CRPropertyID)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 ((const char *) "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 ;
+ int dir;
+
+ g_return_val_if_fail (a_style && a_value,
+ CR_BAD_PARAM_ERROR) ;
+ cur_term = a_value ;
+
+ if (!cur_term)
+ return CR_ERROR ;
+
+ for (dir = (int) DIR_TOP ; dir < (int)NB_DIRS ; dir++) {
+ enum CRDirection direction = (enum CRDirection)dir;
+ 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 ;
+ int dir;
+
+ 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 (dir = (int)DIR_TOP ; dir < (int)NB_DIRS ; dir++) {
+ enum CRDirection direction = (enum CRDirection)dir;
+ 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 gchar *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 gchar *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 status;
+}
+
+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) {
+ /*unknown 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 successful 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,
+ (const guchar *) a_value->content.str->stryng->str);
+
+ }
+ if (status != CR_OK) {
+ cr_rgb_set_from_name (rgb_color, (const guchar *) "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)
+{
+ int dir;
+
+ g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
+
+ for (dir = 0; dir < (int)NB_DIRS; dir++) {
+ set_prop_border_x_from_value (a_style,
+ a_value,
+ (enum CRDirection)dir);
+ }
+
+ return CR_OK;
+}
+
+static enum CRStatus
+set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
+{
+ CRTerm *cur_term = NULL;
+ int dir;
+ 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 (dir = 0; dir < (int)NB_DIRS; dir++) {
+ set_prop_padding_x_from_value (a_style,
+ cur_term, (enum CRDirection)dir);
+ }
+ 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;
+ int dir;
+ 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 (dir = 0; dir < (int)NB_DIRS; dir++) {
+ set_prop_margin_x_from_value(a_style,
+ cur_term, (enum CRDirection)dir);
+ }
+ 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,
+ (guchar *) 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->stryng->str,
+ "xx-small")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_XX_SMALL;
+
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "x-small")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_X_SMALL;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "small")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_SMALL;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str, "medium")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_MEDIUM;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "large")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_LARGE;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "x-large")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_X_LARGE;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "xx-large")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type =
+ PREDEFINED_ABSOLUTE_FONT_SIZE;
+ a_style->font_size.sv.value.predefined =
+ FONT_SIZE_XX_LARGE;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "larger")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
+ a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
+ } else if (a_value->content.str
+ && a_value->content.str->stryng
+ && a_value->content.str->stryng->str
+ && !strcmp (a_value->content.str->stryng->str,
+ "smaller")) {
+ status = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+
+ a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
+ a_style->font_size.sv.value.relative =
+ FONT_SIZE_SMALLER;
+ } else 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 = init_style_font_size_field (a_style);
+ g_return_val_if_fail (status == CR_OK, status);
+ a_style->font_size.sv.type = INHERITED_FONT_SIZE;
+
+ } else {
+ cr_utils_trace_info ("Unknown value of font-size") ;
+ status = init_style_font_size_field (a_style);
+ 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.sv.type = ABSOLUTE_FONT_SIZE;
+ cr_num_copy (&a_style->font_size.sv.value.absolute,
+ a_value->content.num) ;
+ }
+ break;
+
+ default:
+ status = init_style_font_size_field (a_style);
+ 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->stryng
+ && a_value->content.str->stryng->str) {
+ if (!strcmp (a_value->content.str->stryng->str, "normal")) {
+ a_style->font_style = FONT_STYLE_NORMAL;
+ } else if (!strcmp
+ (a_value->content.str->stryng->str,
+ "italic")) {
+ a_style->font_style = FONT_STYLE_ITALIC;
+ } else if (!strcmp
+ (a_value->content.str->stryng->str,
+ "oblique")) {
+ a_style->font_style = FONT_STYLE_OBLIQUE;
+ } else if (!strcmp
+ (a_value->content.str->stryng->str,
+ "inherit")) {
+ a_style->font_style = FONT_STYLE_INHERIT;
+ } 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->stryng
+ && a_value->content.str->stryng->str) {
+ if (!strcmp (a_value->content.str->stryng->str,
+ "normal")) {
+ a_style->font_weight = FONT_WEIGHT_NORMAL;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "bold")) {
+ a_style->font_weight = FONT_WEIGHT_BOLD;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "bolder")) {
+ a_style->font_weight = FONT_WEIGHT_BOLDER;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "lighter")) {
+ a_style->font_weight = FONT_WEIGHT_LIGHTER;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "inherit")) {
+ a_style->font_weight = FONT_WEIGHT_INHERIT;
+
+ } 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;
+}
+
+static enum CRStatus
+set_prop_white_space_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) {
+ if (!strcmp (a_value->content.str->stryng->str, "normal")) {
+ a_style->white_space = WHITE_SPACE_NORMAL;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "pre")) {
+ a_style->white_space = WHITE_SPACE_PRE;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "nowrap")) {
+ a_style->white_space = WHITE_SPACE_NOWRAP;
+ } else if (!strcmp (a_value->content.str->stryng->str,
+ "inherit")) {
+ a_style->white_space = WHITE_SPACE_INHERIT;
+ } else {
+ status = CR_UNKNOWN_PROP_VAL_ERROR;
+ }
+ }
+ break;
+ default:
+ status = CR_UNKNOWN_PROP_VAL_ERROR;
+ break;
+ }
+
+ return status;
+}
+
+/******************
+ *Public methods
+ ******************/
+
+/**
+ *Default constructor of #CRStyle.
+ *@param a_set_props_to_initial_values if TRUE, the style properties
+ *will be set to the default values. Only the style properties of the
+ *root box should be set to their initial values.
+ *Otherwise, the style values are set to their default value.
+ *Read the CSS2 spec, chapters 6.1.1 to 6.2.
+ */
+CRStyle *
+cr_style_new (gboolean a_set_props_to_initial_values)
+{
+ CRStyle *result = NULL;
+
+ result = (CRStyle *) 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++;
+
+ if (a_set_props_to_initial_values == TRUE) {
+ cr_style_set_props_to_initial_values (result);
+ } else {
+ cr_style_set_props_to_default_values (result);
+ }
+
+ return result;
+}
+
+/**
+ *Sets the style properties to their default values according to the css2 spec
+ * i.e inherit if the property is inherited, its initial value otherwise.
+ *@param a_this the current instance of #CRStyle.
+ *@return CR_OK upon successful completion, an error code otherwise.
+ */
+enum CRStatus
+cr_style_set_props_to_default_values (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:
+ /*
+ *REVIEW: color is inherited and the default value is
+ *ua dependent.
+ */
+ cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
+ TRUE) ;
+ break;
+
+ /*default background color is white */
+ case RGB_PROP_BACKGROUND_COLOR:
+ /* TODO: the default value should be transparent */
+ cr_rgb_set (&a_this->rgb_props[i].sv,
+ 255, 255, 255, FALSE);
+ cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
+ TRUE) ;
+ break;
+
+ default:
+ /*
+ *TODO: for BORDER_COLOR the initial value should
+ * be the same as COLOR
+ */
+ 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_INLINE;
+ a_this->position = POSITION_STATIC;
+ a_this->float_type = FLOAT_NONE;
+ a_this->parent_style = NULL;
+ a_this->font_style = FONT_STYLE_INHERIT;
+ a_this->font_variant = FONT_VARIANT_INHERIT;
+ a_this->font_weight = FONT_WEIGHT_INHERIT;
+ a_this->font_family = NULL;
+
+ cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
+ cr_font_size_clear (&a_this->font_size.cv) ;
+ cr_font_size_clear (&a_this->font_size.av) ;
+
+ /* To make the inheritance resolution possible and efficient */
+ a_this->inherited_props_resolved = FALSE ;
+ return CR_OK;
+}
+
+/**
+ *Sets the style properties to their initial value according to the css2 spec.
+ *This function should be used to initialize the style of the root element
+ *of an xml tree.
+ *Some properties are user agent dependent like font-family, and
+ *are not initialized, read the spec to make you renderer compliant.
+ *@param a_this the current instance of #CRStyle.
+ *@return CR_OK upon successful completion, an error code otherwise.
+ */
+enum CRStatus
+cr_style_set_props_to_initial_values (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:
+ cr_num_set (&a_this->num_props[i].sv, 800,
+ NUM_LENGTH_PX) ;
+ break ;
+ 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);
+ cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
+ TRUE) ;
+ 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->font_style = FONT_STYLE_NORMAL;
+ a_this->font_variant = FONT_VARIANT_NORMAL;
+ a_this->font_weight = FONT_WEIGHT_NORMAL;
+ a_this->font_stretch = FONT_STRETCH_NORMAL;
+ a_this->white_space = WHITE_SPACE_NORMAL;
+ cr_font_size_set_predefined_absolute_font_size
+ (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
+ a_this->inherited_props_resolved = FALSE ;
+
+ return CR_OK;
+}
+
+/**
+ *Resolves the inherited properties.
+ *The function sets the "inherited" properties to either the value of
+ *their parent properties.
+ *This function is *NOT* recursive. So the inherited properties of
+ *the parent style must have been resolved prior to calling this function.
+ *@param a_this the instance where
+ *@return CR_OK if a root node is found and the propagation is successful,
+ *an error code otherwise
+ */
+enum CRStatus
+cr_style_resolve_inherited_properties (CRStyle *a_this)
+{
+ enum CRStatus ret = CR_OK;
+ glong i = 0;
+
+ g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
+ g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
+
+ if (a_this->inherited_props_resolved == TRUE)
+ return CR_OK ;
+
+ for (i=0 ; i < NB_NUM_PROPS ;i++) {
+ if (a_this->num_props[i].sv.type == NUM_INHERIT) {
+ cr_num_copy (&a_this->num_props[i].cv,
+ &a_this->parent_style->num_props[i].cv);
+ }
+ }
+ for (i=0; i < NB_RGB_PROPS; i++) {
+ if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
+ cr_rgb_copy (
+ &a_this->rgb_props[i].cv,
+ &a_this->parent_style->rgb_props[i].cv);
+ }
+ }
+ for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
+ if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
+ a_this->border_style_props[i] =
+ a_this->parent_style->border_style_props[i];
+ }
+ }
+
+ if (a_this->display == DISPLAY_INHERIT) {
+ a_this->display = a_this->parent_style->display;
+ }
+ if (a_this->position == POSITION_INHERIT) {
+ a_this->position = a_this->parent_style->position;
+ }
+ if (a_this->float_type == FLOAT_INHERIT) {
+ a_this->float_type = a_this->parent_style->float_type;
+ }
+ if (a_this->font_style == FONT_STYLE_INHERIT) {
+ a_this->font_style = a_this->parent_style->font_style;
+ }
+ if (a_this->font_variant == FONT_VARIANT_INHERIT) {
+ a_this->font_variant = a_this->parent_style->font_variant;
+ }
+ if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
+ a_this->font_weight = a_this->parent_style->font_weight;
+ }
+ if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
+ a_this->font_stretch = a_this->parent_style->font_stretch;
+ }
+ /*NULL is inherit marker for font_famiy*/
+ if (a_this->font_family == NULL) {
+ a_this->font_family = a_this->parent_style->font_family;
+ }
+ if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
+ cr_font_size_copy (&a_this->font_size.cv,
+ &a_this->parent_style->font_size.cv) ;
+ }
+ a_this->inherited_props_resolved = TRUE ;
+ return ret;
+}
+
+/**
+ *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 successful 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->stryng
+ && a_decl->property->stryng->str,
+ CR_BAD_PARAM_ERROR);
+
+ prop_id = cr_style_get_prop_id
+ ((const guchar *) a_decl->property->stryng->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_WIDTH:
+ status = set_prop_border_width_from_value (a_this, value) ;
+ 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_STYLE:
+ status = set_prop_border_style_from_value (a_this, value) ;
+ 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_RIGHT);
+ 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_LEFT);
+ 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 (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;
+
+ case PROP_ID_WHITE_SPACE:
+ status = set_prop_white_space_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 successful 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 (FALSE);
+ if (!result) {
+ cr_utils_trace_info ("Out of memory");
+ return NULL;
+ }
+ cr_style_copy (result, a_this);
+ return result;
+}
+
+/**
+ *Copies a style data structure into another.
+ *TODO: this is actually broken because it's based
+ *on memcpy although some data structures of CRStyle should
+ *be properly duplicated.
+ *@param a_dest the destination style datastructure
+ *@param a_src the source style datastructure.
+ *@return CR_OK upon successful completion, an error code otherwise
+ */
+enum CRStatus
+cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
+{
+ g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
+
+ memcpy (a_dest, a_src, sizeof (CRStyle));
+ return CR_OK;
+}
+
+/**
+ *dump a CRNumpPropVal in a string.
+ *@param a_prop_val the numerical property value to dump
+ *@param a_str the string to dump the numerical property into.
+ *Note that the string value is appended to a_str.
+ *@param a_nb_indent the number white chars of indentation.
+ */
+enum CRStatus
+cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
+ GString * a_str, guint a_nb_indent)
+{
+ enum CRStatus status = CR_OK;
+ guchar *tmp_str = NULL;
+ GString *str = NULL;
+
+ g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
+
+ str = g_string_new (NULL);
+ cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
+ g_string_append (str, "NumPropVal {");
+ tmp_str = cr_num_to_string (&a_prop_val->sv);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "sv: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+
+ tmp_str = cr_num_to_string (&a_prop_val->cv);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "cv: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+
+ tmp_str = cr_num_to_string (&a_prop_val->av);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "av: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+ g_string_append (str, "}");
+ g_string_append (a_str, str->str);
+ status = CR_OK;
+ cleanup:
+
+ if (tmp_str) {
+ g_free (tmp_str);
+ tmp_str = NULL;
+ }
+ if (str) {
+ g_string_free (str, TRUE);
+ }
+ return status;
+}
+
+enum CRStatus
+cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
+ GString * a_str, guint a_nb_indent)
+{
+ enum CRStatus status = CR_OK;
+ guchar *tmp_str = NULL;
+ GString *str = NULL;
+
+ g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
+
+ str = g_string_new (NULL);
+
+ cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
+ g_string_append (str, "RGBPropVal {");
+ tmp_str = cr_rgb_to_string (&a_prop_val->sv);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "sv: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+ tmp_str = cr_rgb_to_string (&a_prop_val->cv);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "cv: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+ tmp_str = cr_rgb_to_string (&a_prop_val->av);
+ if (!tmp_str) {
+ status = CR_ERROR;
+ goto cleanup;
+ }
+ g_string_append_printf (str, "av: %s ", tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+
+ g_string_append (str, "}");
+ g_string_append (a_str, str->str);
+ status = CR_OK;
+ cleanup:
+
+ if (tmp_str) {
+ g_free (tmp_str);
+ tmp_str = NULL;
+ }
+ if (str) {
+ g_string_free (str, TRUE);
+ }
+ return status;
+}
+
+enum CRStatus
+cr_style_border_style_to_string (enum CRBorderStyle a_prop,
+ GString * a_str, guint a_nb_indent)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
+
+ switch (a_prop) {
+ case BORDER_STYLE_NONE:
+ str = (gchar *) "border-style-none";
+ break;
+ case BORDER_STYLE_HIDDEN:
+ str = (gchar *) "border-style-hidden";
+ break;
+ case BORDER_STYLE_DOTTED:
+ str = (gchar *) "border-style-dotted";
+ break;
+ case BORDER_STYLE_DASHED:
+ str = (gchar *) "border-style-dashed";
+ break;
+ case BORDER_STYLE_SOLID:
+ str = (gchar *) "border-style-solid";
+ break;
+ case BORDER_STYLE_DOUBLE:
+ str = (gchar *) "border-style-double";
+ break;
+ case BORDER_STYLE_GROOVE:
+ str = (gchar *) "border-style-groove";
+ break;
+ case BORDER_STYLE_RIDGE:
+ str = (gchar *) "border-style-ridge";
+ break;
+ case BORDER_STYLE_INSET:
+ str = (gchar *) "border-style-inset";
+ break;
+ case BORDER_STYLE_OUTSET:
+ str = (gchar *) "border-style-outset";
+ break;
+ default:
+ str = (gchar *) "unknown border style";
+ break;
+ }
+ cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
+ g_string_append (a_str, str);
+ return CR_OK;
+}
+
+enum CRStatus
+cr_style_display_type_to_string (enum CRDisplayType a_code,
+ GString * a_str, guint a_nb_indent)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
+
+ switch (a_code) {
+ case DISPLAY_NONE:
+ str = (gchar *) "display-none";
+ break;
+ case DISPLAY_INLINE:
+ str = (gchar *) "display-inline";
+ break;
+ case DISPLAY_BLOCK:
+ str = (gchar *) "display-block";
+ break;
+ case DISPLAY_LIST_ITEM:
+ str = (gchar *) "display-list-item";
+ break;
+ case DISPLAY_RUN_IN:
+ str = (gchar *) "display-run-in";
+ break;
+ case DISPLAY_COMPACT:
+ str = (gchar *) "display-compact";
+ break;
+ case DISPLAY_MARKER:
+ str = (gchar *) "display-marker";
+ break;
+ case DISPLAY_TABLE:
+ str = (gchar *) "display-table";
+ break;
+ case DISPLAY_INLINE_TABLE:
+ str = (gchar *) "display-inline-table";
+ break;
+ case DISPLAY_TABLE_ROW_GROUP:
+ str = (gchar *) "display-table-row-group";
+ break;
+ case DISPLAY_TABLE_HEADER_GROUP:
+ str = (gchar *) "display-table-header-group";
+ break;
+ case DISPLAY_TABLE_FOOTER_GROUP:
+ str = (gchar *) "display-table-footer-group";
+ break;
+ case DISPLAY_TABLE_ROW:
+ str = (gchar *) "display-table-row";
+ break;
+ case DISPLAY_TABLE_COLUMN_GROUP:
+ str = (gchar *) "display-table-column-group";
+ break;
+ case DISPLAY_TABLE_COLUMN:
+ str = (gchar *) "display-table-column";
+ break;
+ case DISPLAY_TABLE_CELL:
+ str = (gchar *) "display-table-cell";
+ break;
+ case DISPLAY_TABLE_CAPTION:
+ str = (gchar *) "display-table-caption";
+ break;
+ case DISPLAY_INHERIT:
+ str = (gchar *) "display-inherit";
+ break;
+ default:
+ str = (gchar *) "unknown display property";
+ break;
+ }
+ cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
+ g_string_append (a_str, str);
+ return CR_OK;
+
+}
+
+enum CRStatus
+cr_style_position_type_to_string (enum CRPositionType a_code,
+ GString * a_str, guint a_nb_indent)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
+
+ switch (a_code) {
+ case POSITION_STATIC:
+ str = (gchar *) "position-static";
+ break;
+ case POSITION_RELATIVE:
+ str = (gchar *) "position-relative";
+ break;
+ case POSITION_ABSOLUTE:
+ str = (gchar *) "position-absolute";
+ break;
+ case POSITION_FIXED:
+ str = (gchar *) "position-fixed";
+ break;
+ case POSITION_INHERIT:
+ str = (gchar *) "position-inherit";
+ break;
+ default:
+ str = (gchar *) "unknown static property";
+ }
+ cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
+ g_string_append (a_str, str);
+ return CR_OK;
+}
+
+enum CRStatus
+cr_style_float_type_to_string (enum CRFloatType a_code,
+ GString * a_str, guint a_nb_indent)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
+
+ switch (a_code) {
+ case FLOAT_NONE:
+ str = (gchar *) "float-none";
+ break;
+ case FLOAT_LEFT:
+ str = (gchar *) "float-left";
+ break;
+ case FLOAT_RIGHT:
+ str = (gchar *) "float-right";
+ break;
+ case FLOAT_INHERIT:
+ str = (gchar *) "float-inherit";
+ break;
+ default:
+ str = (gchar *) "unknown float property value";
+ break;
+ }
+ cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
+ g_string_append (a_str, str);
+ return CR_OK;
+}
+
+enum CRStatus
+cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
+ GString * a_str, guint a_nb_indent)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
+
+ switch (a_code) {
+ case WHITE_SPACE_NORMAL:
+ str = (gchar *) "normal";
+ break;
+ case WHITE_SPACE_PRE:
+ str = (gchar *) "pre";
+ break;
+ case WHITE_SPACE_NOWRAP:
+ str = (gchar *) "nowrap";
+ break;
+ case WHITE_SPACE_INHERIT:
+ str = (gchar *) "inherited";
+ break;
+ default:
+ str = (gchar *) "unknown white space property value";
+ break;
+ }
+ cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
+ g_string_append (a_str, str);
+ return CR_OK;
+}
+
+/**
+ *Serializes in instance of #CRStyle into
+ *a string
+ *@param a_this the instance of #CRStyle to serialize
+ *@param a_str the string to serialise the style into.
+ *if *a_str is NULL, a new GString is instantiated, otherwise
+ *the style serialisation is appended to the existed *a_str
+ *@param the number of white space char to use for indentation.
+ *@return CR_OK upon successful completion, an error code otherwise.
+ */
+enum CRStatus
+cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
+{
+ const gint INTERNAL_INDENT = 2;
+ gint indent = a_nb_indent + INTERNAL_INDENT;
+ gchar *tmp_str = NULL;
+ GString *str = NULL;
+ gint i = 0;
+
+ g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
+
+ if (!*a_str) {
+ str = g_string_new (NULL);
+ } else {
+ str = *a_str;
+ }
+ cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
+ g_string_append (str, "style {\n");
+
+ /*loop over the num_props and to_string() them */
+ for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
+ /*
+ *to_string() the name of the num_prop
+ *(using num_prop_code_to_string)
+ *before outputting it value
+ */
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = (gchar *) num_prop_code_to_string ((enum CRNumProp) i);
+ if (tmp_str) {
+ g_string_append_printf (str, "%s: ", tmp_str);
+ } else {
+ g_string_append (str, "NULL");
+ }
+ tmp_str = NULL;
+ cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
+ a_nb_indent +
+ INTERNAL_INDENT);
+ g_string_append (str, "\n");
+ }
+ /*loop over the rgb_props and to_string() them all */
+ for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
+ tmp_str = (gchar *) rgb_prop_code_to_string ((enum CRRgbProp) i);
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ if (tmp_str) {
+ g_string_append_printf (str, "%s: ", tmp_str);
+ } else {
+ g_string_append (str, "NULL: ");
+ }
+ tmp_str = NULL;
+ cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
+ a_nb_indent +
+ INTERNAL_INDENT);
+ g_string_append (str, "\n");
+ }
+ /*loop over the border_style_props and to_string() them */
+ for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
+ tmp_str = (gchar *) border_style_prop_code_to_string ((enum CRBorderStyleProp) i);
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ if (tmp_str) {
+ g_string_append_printf (str, "%s: ", tmp_str);
+ } else {
+ g_string_append (str, "NULL: ");
+ }
+ tmp_str = NULL;
+ cr_style_border_style_to_string (a_this->
+ border_style_props[i], str,
+ 0);
+ g_string_append (str, "\n");
+ }
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ g_string_append (str, "display: ");
+ cr_style_display_type_to_string (a_this->display, str, 0);
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ g_string_append (str, "position: ");
+ cr_style_position_type_to_string (a_this->position, str, 0);
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ g_string_append (str, "float-type: ");
+ cr_style_float_type_to_string (a_this->float_type, str, 0);
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ g_string_append (str, "white-space: ");
+ cr_style_white_space_type_to_string (a_this->white_space, str, 0);
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ g_string_append (str, "font-family: ");
+ tmp_str = (gchar *) cr_font_family_to_string (a_this->font_family, TRUE);
+ if (tmp_str) {
+ g_string_append (str, tmp_str);
+ g_free (tmp_str);
+ tmp_str = NULL;
+ } else {
+ g_string_append (str, "NULL");
+ }
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-size {sv:%s, ",
+ tmp_str) ;
+ } else {
+ g_string_append (str, "font-size {sv:NULL, ");
+ }
+ tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
+ if (tmp_str) {
+ g_string_append_printf (str, "cv:%s, ", tmp_str);
+ } else {
+ g_string_append (str, "cv:NULL, ");
+ }
+ tmp_str = cr_font_size_to_string (&a_this->font_size.av);
+ if (tmp_str) {
+ g_string_append_printf (str, "av:%s}", tmp_str);
+ } else {
+ g_string_append (str, "av:NULL}");
+ }
+
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
+ } else {
+ g_string_append (str, "font-size-adjust: NULL");
+ }
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-style: %s", tmp_str);
+ } else {
+ g_string_append (str, "font-style: NULL");
+ }
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-variant: %s", tmp_str);
+ } else {
+ g_string_append (str, "font-variant: NULL");
+ }
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-weight: %s", tmp_str);
+ } else {
+ g_string_append (str, "font-weight: NULL");
+ }
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+ cr_utils_dump_n_chars2 (' ', str, indent);
+ tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
+ if (tmp_str) {
+ g_string_append_printf (str, "font-stretch: %s", tmp_str);
+ } else {
+ g_string_append (str, "font-stretch: NULL");
+ }
+ tmp_str = NULL;
+ g_string_append (str, "\n");
+
+
+ cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
+ g_string_append (str, "}");
+
+ return CR_OK;
+}
+
+/**
+ *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);
+}
+