ff4ff35918
Red Bear OS is a full fork. All sources must be available from git clone with zero network access. Removed gitignore rules that excluded fetched source trees under recipes/*/source/, local/recipes/kde/*/source/, local/recipes/qt/*/source/, and vendor source trees. Build artifacts (target/, build/, source.tar, *.o, *.so) remain excluded. 127291 files added — kernel, relibc, base, bootloader, pkgar, all KDE/Qt frameworks, mesa, wayland, DRM drivers, and every other recipe source.
2863 lines
99 KiB
C
2863 lines
99 KiB
C
/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
|
|
|
|
/* libcroco - Library for parsing and applying CSS
|
|
* Copyright (C) 2006-2019 Free Software Foundation, Inc.
|
|
*
|
|
* This file is not part of the GNU gettext program, but is used with
|
|
* GNU gettext.
|
|
*
|
|
* The original copyright notice is as follows:
|
|
*/
|
|
|
|
/*
|
|
* This file is part of The Croco Library
|
|
*
|
|
* Copyright (C) 2003-2004 Dodji Seketeli. All Rights Reserved.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <string.h>
|
|
#include "cr-style.h"
|
|
|
|
/**
|
|
*@file
|
|
*The definition of the #CRStyle class.
|
|
*/
|
|
|
|
/**
|
|
*A property ID.
|
|
*Each supported css property has an ID which is
|
|
*an entry into a property "population" jump table.
|
|
*each entry of the property population jump table
|
|
*contains code to tranform the literal form of
|
|
*a property value into a strongly typed value.
|
|
*/
|
|
enum CRPropertyID {
|
|
PROP_ID_NOT_KNOWN = 0,
|
|
PROP_ID_PADDING_TOP,
|
|
PROP_ID_PADDING_RIGHT,
|
|
PROP_ID_PADDING_BOTTOM,
|
|
PROP_ID_PADDING_LEFT,
|
|
PROP_ID_PADDING,
|
|
PROP_ID_BORDER_TOP_WIDTH,
|
|
PROP_ID_BORDER_RIGHT_WIDTH,
|
|
PROP_ID_BORDER_BOTTOM_WIDTH,
|
|
PROP_ID_BORDER_LEFT_WIDTH,
|
|
PROP_ID_BORDER_WIDTH,
|
|
PROP_ID_BORDER_TOP_STYLE,
|
|
PROP_ID_BORDER_RIGHT_STYLE,
|
|
PROP_ID_BORDER_BOTTOM_STYLE,
|
|
PROP_ID_BORDER_LEFT_STYLE,
|
|
PROP_ID_BORDER_STYLE,
|
|
PROP_ID_BORDER_TOP_COLOR,
|
|
PROP_ID_BORDER_RIGHT_COLOR,
|
|
PROP_ID_BORDER_BOTTOM_COLOR,
|
|
PROP_ID_BORDER_LEFT_COLOR,
|
|
PROP_ID_BORDER_TOP,
|
|
PROP_ID_BORDER_RIGHT,
|
|
PROP_ID_BORDER_BOTTOM,
|
|
PROP_ID_BORDER_LEFT,
|
|
PROP_ID_BORDER,
|
|
PROP_ID_MARGIN_TOP,
|
|
PROP_ID_MARGIN_RIGHT,
|
|
PROP_ID_MARGIN_BOTTOM,
|
|
PROP_ID_MARGIN_LEFT,
|
|
PROP_ID_MARGIN,
|
|
PROP_ID_DISPLAY,
|
|
PROP_ID_POSITION,
|
|
PROP_ID_TOP,
|
|
PROP_ID_RIGHT,
|
|
PROP_ID_BOTTOM,
|
|
PROP_ID_LEFT,
|
|
PROP_ID_FLOAT,
|
|
PROP_ID_WIDTH,
|
|
PROP_ID_COLOR,
|
|
PROP_ID_BACKGROUND_COLOR,
|
|
PROP_ID_FONT_FAMILY,
|
|
PROP_ID_FONT_SIZE,
|
|
PROP_ID_FONT_STYLE,
|
|
PROP_ID_FONT_WEIGHT,
|
|
PROP_ID_WHITE_SPACE,
|
|
/*should be the last one. */
|
|
NB_PROP_IDS
|
|
};
|
|
|
|
typedef struct _CRPropertyDesc CRPropertyDesc;
|
|
|
|
struct _CRPropertyDesc {
|
|
const 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, 0}
|
|
};
|
|
|
|
/**
|
|
*A the key/value pair of this hash table
|
|
*are:
|
|
*key => name of the the css propertie found in gv_prop_table
|
|
*value => matching property id found in gv_prop_table.
|
|
*So this hash table is here just to retrieval of a property id
|
|
*from a property name.
|
|
*/
|
|
static GHashTable *gv_prop_hash = NULL;
|
|
|
|
/**
|
|
*incremented by each new instance of #CRStyle
|
|
*and decremented at the it destroy time.
|
|
*When this reaches zero, gv_prop_hash is destroyed.
|
|
*/
|
|
static gulong gv_prop_hash_ref_count = 0;
|
|
|
|
struct CRNumPropEnumDumpInfo {
|
|
enum CRNumProp code;
|
|
const gchar *str;
|
|
};
|
|
|
|
static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
|
|
{NUM_PROP_TOP, "top"},
|
|
{NUM_PROP_RIGHT, "right"},
|
|
{NUM_PROP_BOTTOM, "bottom"},
|
|
{NUM_PROP_LEFT, "left"},
|
|
{NUM_PROP_PADDING_TOP, "padding-top"},
|
|
{NUM_PROP_PADDING_RIGHT, "padding-right"},
|
|
{NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
|
|
{NUM_PROP_PADDING_LEFT, "padding-left"},
|
|
{NUM_PROP_BORDER_TOP, "border-top"},
|
|
{NUM_PROP_BORDER_RIGHT, "border-right"},
|
|
{NUM_PROP_BORDER_BOTTOM, "border-bottom"},
|
|
{NUM_PROP_BORDER_LEFT, "border-left"},
|
|
{NUM_PROP_MARGIN_TOP, "margin-top"},
|
|
{NUM_PROP_MARGIN_RIGHT, "margin-right"},
|
|
{NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
|
|
{NUM_PROP_MARGIN_LEFT, "margin-left"},
|
|
{NUM_PROP_WIDTH, "width"},
|
|
{0, NULL}
|
|
};
|
|
|
|
struct CRRgbPropEnumDumpInfo {
|
|
enum CRRgbProp code;
|
|
const gchar *str;
|
|
};
|
|
|
|
static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
|
|
{RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
|
|
{RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
|
|
{RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
|
|
{RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
|
|
{RGB_PROP_COLOR, "color"},
|
|
{RGB_PROP_BACKGROUND_COLOR, "background-color"},
|
|
{0, NULL}
|
|
};
|
|
|
|
struct CRBorderStylePropEnumDumpInfo {
|
|
enum CRBorderStyleProp code;
|
|
const gchar *str;
|
|
|
|
};
|
|
|
|
static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
|
|
= {
|
|
{BORDER_STYLE_PROP_TOP, "border-style-top"},
|
|
{BORDER_STYLE_PROP_RIGHT, "border-style-right"},
|
|
{BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
|
|
{BORDER_STYLE_PROP_LEFT, "border-style-left"},
|
|
{0, NULL}
|
|
};
|
|
|
|
static enum CRStatus
|
|
cr_style_init_properties (void);
|
|
|
|
enum CRDirection {
|
|
DIR_TOP = 0,
|
|
DIR_RIGHT,
|
|
DIR_BOTTOM,
|
|
DIR_LEFT,
|
|
|
|
/*must be the last one */
|
|
NB_DIRS
|
|
};
|
|
|
|
static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
|
|
|
|
static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
|
|
|
|
static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
|
|
a_code);
|
|
|
|
static enum CRStatus
|
|
set_prop_padding_x_from_value (CRStyle * a_style,
|
|
CRTerm * a_value, enum CRDirection a_dir);
|
|
|
|
static enum CRStatus
|
|
set_prop_border_x_width_from_value (CRStyle * a_style,
|
|
CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
static enum CRStatus
|
|
set_prop_border_width_from_value (CRStyle *a_style,
|
|
CRTerm *a_value) ;
|
|
|
|
static enum CRStatus
|
|
set_prop_border_x_style_from_value (CRStyle * a_style,
|
|
CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
static enum CRStatus
|
|
set_prop_border_style_from_value (CRStyle *a_style,
|
|
CRTerm *a_value) ;
|
|
|
|
static enum CRStatus
|
|
set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
|
|
static enum CRStatus
|
|
set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
|
|
static enum CRStatus
|
|
set_prop_float (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_width (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_color (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
|
|
static enum CRStatus
|
|
set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir);
|
|
|
|
static enum CRStatus
|
|
set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
init_style_font_size_field (CRStyle * a_style);
|
|
|
|
static enum CRStatus
|
|
set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static enum CRStatus
|
|
set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
|
|
|
|
static const gchar *
|
|
num_prop_code_to_string (enum CRNumProp a_code)
|
|
{
|
|
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 = g_hash_table_lookup (gv_prop_hash, a_prop);
|
|
if (!raw_id) {
|
|
return PROP_ID_NOT_KNOWN;
|
|
}
|
|
return GPOINTER_TO_INT (raw_id);
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_padding_x_from_value (CRStyle * a_style,
|
|
CRTerm * a_value, enum CRDirection a_dir)
|
|
{
|
|
enum CRStatus status = CR_OK;
|
|
CRNum *num_val = NULL;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
|
|
return CR_BAD_PARAM_ERROR;
|
|
|
|
switch (a_dir) {
|
|
case DIR_TOP:
|
|
num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
|
|
break;
|
|
|
|
case DIR_BOTTOM:
|
|
num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
|
|
break;
|
|
|
|
default:
|
|
return CR_BAD_PARAM_ERROR;
|
|
}
|
|
|
|
if (a_value->type == TERM_IDENT) {
|
|
if (a_value->content.str
|
|
&& a_value->content.str->stryng
|
|
&& a_value->content.str->stryng->str
|
|
&& !strncmp ((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 ;
|
|
enum CRDirection direction = DIR_TOP ;
|
|
|
|
g_return_val_if_fail (a_style && a_value,
|
|
CR_BAD_PARAM_ERROR) ;
|
|
cur_term = a_value ;
|
|
|
|
if (!cur_term)
|
|
return CR_ERROR ;
|
|
|
|
for (direction = DIR_TOP ;
|
|
direction < NB_DIRS ; direction ++) {
|
|
set_prop_border_x_width_from_value (a_style,
|
|
cur_term,
|
|
direction) ;
|
|
}
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term)
|
|
return CR_OK ;
|
|
set_prop_border_x_width_from_value (a_style, cur_term,
|
|
DIR_RIGHT) ;
|
|
set_prop_border_x_width_from_value (a_style, cur_term,
|
|
DIR_LEFT) ;
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term)
|
|
return CR_OK ;
|
|
set_prop_border_x_width_from_value (a_style, cur_term,
|
|
DIR_BOTTOM) ;
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term)
|
|
return CR_OK ;
|
|
set_prop_border_x_width_from_value (a_style, cur_term,
|
|
DIR_LEFT) ;
|
|
|
|
return CR_OK ;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_border_x_style_from_value (CRStyle * a_style,
|
|
CRTerm * a_value, enum CRDirection a_dir)
|
|
{
|
|
enum CRStatus status = CR_OK;
|
|
enum CRBorderStyle *border_style_ptr = NULL;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
switch (a_dir) {
|
|
case DIR_TOP:
|
|
border_style_ptr = &a_style->
|
|
border_style_props[BORDER_STYLE_PROP_TOP];
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
border_style_ptr =
|
|
&a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
|
|
break;
|
|
|
|
case DIR_BOTTOM:
|
|
border_style_ptr = &a_style->
|
|
border_style_props[BORDER_STYLE_PROP_BOTTOM];
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
border_style_ptr = &a_style->
|
|
border_style_props[BORDER_STYLE_PROP_LEFT];
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (a_value->type != TERM_IDENT || !a_value->content.str) {
|
|
return CR_UNKNOWN_TYPE_ERROR;
|
|
}
|
|
|
|
if (!strncmp ("none",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("none")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_NONE;
|
|
} else if (!strncmp ("hidden",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("hidden")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_HIDDEN;
|
|
} else if (!strncmp ("dotted",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("dotted")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_DOTTED;
|
|
} else if (!strncmp ("dashed",
|
|
a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_DASHED;
|
|
} else if (!strncmp ("solid",
|
|
a_value->content.str->stryng->str, sizeof ("solid")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_SOLID;
|
|
} else if (!strncmp ("double",
|
|
a_value->content.str->stryng->str, sizeof ("double")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_DOUBLE;
|
|
} else if (!strncmp ("groove",
|
|
a_value->content.str->stryng->str, sizeof ("groove")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_GROOVE;
|
|
} else if (!strncmp ("ridge",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("ridge")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_RIDGE;
|
|
} else if (!strncmp ("inset",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("inset")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_INSET;
|
|
} else if (!strncmp ("outset",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("outset")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_OUTSET;
|
|
} else if (!strncmp ("inherit",
|
|
a_value->content.str->stryng->str,
|
|
sizeof ("inherit")-1)) {
|
|
*border_style_ptr = BORDER_STYLE_INHERIT;
|
|
} else {
|
|
status = CR_UNKNOWN_TYPE_ERROR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_border_style_from_value (CRStyle *a_style,
|
|
CRTerm *a_value)
|
|
{
|
|
CRTerm *cur_term = NULL ;
|
|
enum CRDirection direction = DIR_TOP ;
|
|
|
|
g_return_val_if_fail (a_style && a_value,
|
|
CR_BAD_PARAM_ERROR) ;
|
|
|
|
cur_term = a_value ;
|
|
if (!cur_term || cur_term->type != TERM_IDENT) {
|
|
return CR_ERROR ;
|
|
}
|
|
|
|
for (direction = DIR_TOP ;
|
|
direction < NB_DIRS ;
|
|
direction ++) {
|
|
set_prop_border_x_style_from_value (a_style,
|
|
cur_term,
|
|
direction) ;
|
|
}
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term || cur_term->type != TERM_IDENT) {
|
|
return CR_OK ;
|
|
}
|
|
|
|
set_prop_border_x_style_from_value (a_style, cur_term,
|
|
DIR_RIGHT) ;
|
|
set_prop_border_x_style_from_value (a_style, cur_term,
|
|
DIR_LEFT) ;
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term || cur_term->type != TERM_IDENT) {
|
|
return CR_OK ;
|
|
}
|
|
set_prop_border_x_style_from_value (a_style, cur_term,
|
|
DIR_BOTTOM) ;
|
|
|
|
cur_term = cur_term->next ;
|
|
if (!cur_term || cur_term->type != TERM_IDENT) {
|
|
return CR_OK ;
|
|
}
|
|
set_prop_border_x_style_from_value (a_style, cur_term,
|
|
DIR_LEFT) ;
|
|
return CR_OK ;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir)
|
|
{
|
|
enum CRStatus status = CR_OK;
|
|
CRNum *num_val = NULL;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
switch (a_dir) {
|
|
case DIR_TOP:
|
|
num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
|
|
break;
|
|
|
|
case DIR_BOTTOM:
|
|
num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (a_value->type) {
|
|
case TERM_IDENT:
|
|
if (a_value->content.str
|
|
&& a_value->content.str->stryng
|
|
&& a_value->content.str->stryng->str
|
|
&& !strcmp (a_value->content.str->stryng->str,
|
|
"inherit")) {
|
|
status = cr_num_set (num_val, 0.0, NUM_INHERIT);
|
|
} else if (a_value->content.str
|
|
&& a_value->content.str->stryng
|
|
&& !strcmp (a_value->content.str->stryng->str,
|
|
"auto")) {
|
|
status = cr_num_set (num_val, 0.0, NUM_AUTO);
|
|
} else {
|
|
status = CR_UNKNOWN_TYPE_ERROR;
|
|
}
|
|
break ;
|
|
|
|
case TERM_NUMBER:
|
|
status = cr_num_copy (num_val, a_value->content.num);
|
|
break;
|
|
|
|
default:
|
|
status = CR_UNKNOWN_TYPE_ERROR;
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
struct CRPropDisplayValPair {
|
|
const 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 successfull completion, an error code otherwise.
|
|
*/
|
|
static enum CRStatus
|
|
set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
|
|
enum CRDirection a_dir)
|
|
{
|
|
CRRgb *rgb_color = NULL;
|
|
enum CRStatus status = CR_OK;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
switch (a_dir) {
|
|
case DIR_TOP:
|
|
rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
|
|
break;
|
|
|
|
case DIR_RIGHT:
|
|
rgb_color =
|
|
&a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
|
|
break;
|
|
|
|
case DIR_BOTTOM:
|
|
rgb_color =
|
|
&a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
|
|
break;
|
|
|
|
case DIR_LEFT:
|
|
rgb_color =
|
|
&a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
|
|
break;
|
|
|
|
default:
|
|
cr_utils_trace_info ("unknown DIR type");
|
|
return CR_BAD_PARAM_ERROR;
|
|
}
|
|
|
|
status = CR_UNKNOWN_PROP_VAL_ERROR;
|
|
|
|
if (a_value->type == TERM_IDENT) {
|
|
if (a_value->content.str
|
|
&& a_value->content.str->stryng
|
|
&& a_value->content.str->stryng->str) {
|
|
status = cr_rgb_set_from_name
|
|
(rgb_color,
|
|
(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)
|
|
{
|
|
enum CRDirection direction = 0;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
for (direction = 0; direction < NB_DIRS; direction++) {
|
|
set_prop_border_x_from_value (a_style,
|
|
a_value,
|
|
direction);
|
|
}
|
|
|
|
return CR_OK;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
|
|
{
|
|
CRTerm *cur_term = NULL;
|
|
enum CRDirection direction = 0;
|
|
enum CRStatus status = CR_OK;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
cur_term = a_value;
|
|
|
|
/*filter the eventual non NUMBER terms some user can have written here*/
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_ERROR ;
|
|
|
|
for (direction = 0; direction < NB_DIRS; direction++) {
|
|
set_prop_padding_x_from_value (a_style, cur_term, direction);
|
|
}
|
|
cur_term = cur_term->next;
|
|
|
|
/*filter non NUMBER terms that some users can have written here...*/
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
/*the user can have just written padding: 1px*/
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
|
|
set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
|
|
return status;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
|
|
{
|
|
CRTerm *cur_term = NULL;
|
|
enum CRDirection direction = 0;
|
|
enum CRStatus status = CR_OK;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
cur_term = a_value;
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
for (direction = 0; direction < NB_DIRS; direction++) {
|
|
set_prop_margin_x_from_value (a_style, cur_term, direction);
|
|
}
|
|
cur_term = cur_term->next;
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
|
|
set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
|
|
|
|
while (cur_term && cur_term->type != TERM_NUMBER) {
|
|
cur_term = cur_term->next;
|
|
}
|
|
if (!cur_term)
|
|
return CR_OK;
|
|
|
|
status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
|
|
|
|
return status;
|
|
}
|
|
|
|
static enum CRStatus
|
|
set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
|
|
{
|
|
CRTerm *cur_term = NULL;
|
|
CRFontFamily *font_family = NULL,
|
|
*cur_ff = NULL,
|
|
*cur_ff2 = NULL;
|
|
|
|
g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
|
|
|
|
if (a_value->type == TERM_IDENT &&
|
|
a_value->content.str &&
|
|
a_value->content.str->stryng &&
|
|
a_value->content.str->stryng->str &&
|
|
!strcmp ("inherit", a_value->content.str->stryng->str))
|
|
{
|
|
font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
|
|
goto out;
|
|
}
|
|
|
|
for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
|
|
switch (cur_term->type) {
|
|
case TERM_IDENT:
|
|
{
|
|
enum CRFontFamilyType font_type;
|
|
|
|
if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str
|
|
&& !strcmp
|
|
(cur_term->content.str->stryng->str,
|
|
"sans-serif")) {
|
|
font_type = FONT_FAMILY_SANS_SERIF;
|
|
} else if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str
|
|
&& !strcmp
|
|
(cur_term->content.str->stryng->str,
|
|
"serif")) {
|
|
font_type = FONT_FAMILY_SERIF;
|
|
} else if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str
|
|
&& !strcmp (cur_term->content.str->stryng->str,
|
|
"cursive")) {
|
|
font_type = FONT_FAMILY_CURSIVE;
|
|
} else if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str
|
|
&& !strcmp (cur_term->content.str->stryng->str,
|
|
"fantasy")) {
|
|
font_type = FONT_FAMILY_FANTASY;
|
|
} else if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str
|
|
&& !strcmp (cur_term->content.str->stryng->str,
|
|
"monospace")) {
|
|
font_type = FONT_FAMILY_MONOSPACE;
|
|
} else {
|
|
/*
|
|
*unknown property value.
|
|
*ignore it.
|
|
*/
|
|
continue;
|
|
}
|
|
|
|
cur_ff = cr_font_family_new (font_type, NULL);
|
|
}
|
|
break;
|
|
|
|
case TERM_STRING:
|
|
{
|
|
if (cur_term->content.str
|
|
&& cur_term->content.str->stryng
|
|
&& cur_term->content.str->stryng->str) {
|
|
cur_ff = cr_font_family_new
|
|
(FONT_FAMILY_NON_GENERIC,
|
|
(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 = 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 successfull 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 dependant.
|
|
*/
|
|
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 dependant 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 successfull 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 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->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 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 (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 stuctures of CRStyle should
|
|
*be properly duplicated.
|
|
*@param a_dest the destination style datastructure
|
|
*@param a_src the source style datastructure.
|
|
*@return CR_OK upon succesfull 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 propertie 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 instanciated, 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 outputing it value
|
|
*/
|
|
cr_utils_dump_n_chars2 (' ', str, indent);
|
|
tmp_str = (gchar *) num_prop_code_to_string (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 (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 (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);
|
|
}
|
|
|