[lasem/properties] Some more work on property lists.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem/properties] Some more work on property lists.
- Date: Wed, 22 Jul 2009 16:15:30 +0000 (UTC)
commit 9233b1a38a6b9bb84353a9e75e776283d5b17e02
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Wed Jul 22 18:14:56 2009 +0200
Some more work on property lists.
src/Makefile.am | 9 +-
src/lasempropertytest.c | 133 -------
src/lsmdomdocument.c | 6 +
src/lsmmathmlmathelement.c | 2 +
src/lsmmathmltableelement.c | 2 +
src/lsmproperties.c | 68 +++--
src/lsmproperties.h | 17 +-
src/lsmsvgcircleelement.c | 1 +
src/lsmsvgelement.c | 14 +-
src/lsmsvgelement.h | 2 +
src/lsmsvgellipseelement.c | 1 +
src/lsmsvggraphic.c | 1 +
src/lsmsvgimageelement.c | 2 +
src/lsmsvglineargradientelement.c | 1 +
src/lsmsvgpathelement.c | 1 +
src/lsmsvgradialgradientelement.c | 1 +
src/lsmsvgrectelement.c | 1 +
src/lsmsvgstyle.c | 686 +++++++++++++++++++++++++++++++++++++
src/lsmsvgstyle.h | 97 ++++++
src/lsmsvgsvgelement.c | 2 +
src/lsmsvgtextelement.c | 1 +
21 files changed, 873 insertions(+), 175 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index e6c115c..948c13d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -180,7 +180,7 @@ liblasem_la_HEADERS = \
lsmsvgview.h \
lsmsvgmatrix.h
-bin_PROGRAMS = lasemtest lasemrender lasempropertytest
+bin_PROGRAMS = lasemtest lasemrender
lasemrender_SOURCES = \
lasemrender.c
@@ -195,10 +195,3 @@ lasemtest_SOURCES = \
lasemtest_LDFLAGS =
lasemtest_LDADD = $(LASEM_LIBS) liblasem.la ../itex2mml/libitex2mml.la
-
-lasempropertytest_SOURCES = \
- lasempropertytest.c
-
-lasempropertytest_LDFLAGS =
-
-lasempropertytest_LDADD = $(LASEM_LIBS) liblasem.la ../itex2mml/libitex2mml.la
diff --git a/src/lsmdomdocument.c b/src/lsmdomdocument.c
index 8dd9879..7d41bb8 100644
--- a/src/lsmdomdocument.c
+++ b/src/lsmdomdocument.c
@@ -24,6 +24,8 @@
#include <lsmdebug.h>
#include <lsmdomtext.h>
+static GObjectClass *parent_class;
+
/* LsmDomNode implementation */
static const char *
@@ -205,6 +207,8 @@ lsm_dom_document_finalize (GObject *object)
g_hash_table_unref (document->elements);
g_hash_table_unref (document->ids);
+
+ parent_class->finalize (object);
}
/* LsmDomDocument class */
@@ -215,6 +219,8 @@ lsm_dom_document_class_init (LsmDomDocumentClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
LsmDomNodeClass *node_class = LSM_DOM_NODE_CLASS (klass);
+ parent_class = g_type_class_peek_parent (klass);
+
object_class->finalize = lsm_dom_document_finalize;
node_class->get_node_name = lsm_dom_document_get_node_name;
diff --git a/src/lsmmathmlmathelement.c b/src/lsmmathmlmathelement.c
index 2ae7673..e494c65 100644
--- a/src/lsmmathmlmathelement.c
+++ b/src/lsmmathmlmathelement.c
@@ -181,6 +181,8 @@ lsm_mathml_math_element_finalize (GObject *object)
LsmMathmlMathElement *math_element = LSM_MATHML_MATH_ELEMENT (object);
lsm_mathml_style_free (math_element->default_style);
+
+ parent_class->finalize (object);
}
/* LsmMathmlMathElement class */
diff --git a/src/lsmmathmltableelement.c b/src/lsmmathmltableelement.c
index c4fa903..31c869a 100644
--- a/src/lsmmathmltableelement.c
+++ b/src/lsmmathmltableelement.c
@@ -457,6 +457,8 @@ lsm_mathml_table_element_finalize (GObject *object)
table->widths = NULL;
table->heights = NULL;
table->depths = NULL;
+
+ parent_class->finalize (object);
}
/* LsmMathmlTableElement class */
diff --git a/src/lsmproperties.c b/src/lsmproperties.c
index 028ca51..a17a46c 100644
--- a/src/lsmproperties.c
+++ b/src/lsmproperties.c
@@ -92,7 +92,7 @@ property_free (LsmProperty *property, const LsmPropertyClass *property_class)
}
void
-lsm_property_list_set_property (GSList **property_list,
+lsm_property_bag_set_property (LsmPropertyBag *property_bag,
LsmPropertyManager *manager,
const char *name, const char *value)
{
@@ -100,7 +100,7 @@ lsm_property_list_set_property (GSList **property_list,
const LsmPropertyInfos *property_infos;
const LsmPropertyClass *property_class;
- g_return_if_fail (property_list != NULL);
+ g_return_if_fail (property_bag != NULL);
g_return_if_fail (manager != NULL);
property_infos = lsm_property_manager_find_infos (manager, name);
@@ -111,34 +111,29 @@ lsm_property_list_set_property (GSList **property_list,
/* We don't check for existing property in the list. The cleanup will be done later. */
- property = g_slice_alloc (property_class->size);
+ property = g_slice_alloc0 (property_class->size);
property->id = property_infos->id;
property->value = g_strdup (value);
if (property_class->init)
property_class->init (property);
- if (property->value != NULL && property_class->from_text) {
- if (!property_class->from_text (property, value)) {
- g_free (property->value);
- property->value = NULL;
- return;
- }
- }
+ if (property->value != NULL && property_class->from_text)
+ property_class->from_text (property, value);
- *property_list = g_slist_prepend (*property_list, property);
+ property_bag->properties = g_slist_prepend (property_bag->properties, property);
}
const char *
-lsm_property_list_get_property (GSList **property_list,
- LsmPropertyManager *manager,
- const char *name)
+lsm_property_bag_get_property (LsmPropertyBag *property_bag,
+ LsmPropertyManager *manager,
+ const char *name)
{
LsmProperty *property = NULL;
const LsmPropertyInfos *property_infos;
GSList *iter;
- g_return_val_if_fail (property_list != NULL, NULL);
+ g_return_val_if_fail (property_bag != NULL, NULL);
g_return_val_if_fail (manager != NULL, NULL);
property_infos = lsm_property_manager_find_infos (manager, name);
@@ -147,7 +142,7 @@ lsm_property_list_get_property (GSList **property_list,
g_message ("Get property with name %s (%d)", name, property_infos->id);
- for (iter = *property_list; iter != NULL; iter = iter->next) {
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
property = iter->data;
if (property->id == property_infos->id)
break;
@@ -160,16 +155,17 @@ lsm_property_list_get_property (GSList **property_list,
}
void
-lsm_property_list_free (GSList **property_list, LsmPropertyManager *manager)
+lsm_property_bag_clean (LsmPropertyBag *property_bag,
+ LsmPropertyManager *manager)
{
LsmProperty *property;
const LsmPropertyInfos *property_infos;
GSList *iter;
- g_return_if_fail (property_list != NULL);
+ g_return_if_fail (property_bag != NULL);
g_return_if_fail (manager != NULL);
- for (iter = *property_list; iter != NULL; iter = iter->next) {
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
property = iter->data;
property_infos = lsm_property_manager_find_infos_by_id (manager, property->id);
@@ -177,19 +173,39 @@ lsm_property_list_free (GSList **property_list, LsmPropertyManager *manager)
property_free (property, property_infos->property_class);
}
- g_slist_free (*property_list);
- *property_list = NULL;
+ g_slist_free (property_bag->properties);
+ property_bag->properties = NULL;
}
-void
-lsm_property_manager_apply_list (LsmPropertyManager *manager, GSList *property_list,
- void **property_set, size_t set_size)
+char *
+lsm_property_bag_serialize (LsmPropertyBag *property_bag,
+ LsmPropertyManager *property_manager)
{
LsmProperty *property;
+ const LsmPropertyInfos *property_infos;
GSList *iter;
+ GString *string;
+ char *c_string;
+
+ g_return_val_if_fail (property_bag != NULL, NULL);
+ g_return_val_if_fail (property_manager != NULL, NULL);
+
+ string = g_string_new ("");
- for (iter = property_list; iter != NULL; iter = iter->next) {
+ for (iter = property_bag->properties; iter != NULL; iter = iter->next) {
property = iter->data;
- property_set[property->id] = property;
+
+ property_infos = lsm_property_manager_find_infos_by_id (property_manager, property->id);
+
+ g_string_append_printf (string, "%s=\"%s\"%s",
+ property_infos->name,
+ property->value,
+ iter->next != NULL ? " ": "");
}
+
+
+ c_string = string->str;
+ g_string_free (string, FALSE);
+
+ return c_string;
}
diff --git a/src/lsmproperties.h b/src/lsmproperties.h
index 565f437..8d1d789 100644
--- a/src/lsmproperties.h
+++ b/src/lsmproperties.h
@@ -36,7 +36,7 @@ typedef struct {
size_t size;
void (*init) (LsmProperty *property);
void (*finalize) (LsmProperty *property);
- gboolean (*from_text) (LsmProperty *property, const char *value);
+ void (*from_text) (LsmProperty *property, const char *value);
char * (*to_text) (LsmProperty *property);
} LsmPropertyClass;
@@ -46,22 +46,25 @@ typedef struct {
const LsmPropertyClass * property_class;
} LsmPropertyInfos;
+typedef struct {
+ GSList *properties;
+} LsmPropertyBag;
+
typedef struct _LsmPropertyManager LsmPropertyManager;
LsmPropertyManager * lsm_property_manager_new (unsigned int n_properties,
const LsmPropertyInfos *property_infos);
void lsm_property_manager_free (LsmPropertyManager *manager);
-void lsm_property_list_set_property (GSList **property_list,
+void lsm_property_bag_set_property (LsmPropertyBag *property_bag,
LsmPropertyManager *manager,
const char *name, const char *value);
-const char * lsm_property_list_get_property (GSList **property_list,
+const char * lsm_property_bag_get_property (LsmPropertyBag *property_bag,
LsmPropertyManager *manager,
const char *name);
-void lsm_property_list_free (GSList **property_list,
+void lsm_property_bag_clean (LsmPropertyBag *property_bag,
LsmPropertyManager *manager);
-
-void lsm_property_manager_apply_list (LsmPropertyManager *manager, GSList *property_list,
- void **property_set, size_t set_size);
+char * lsm_property_bag_serialize (LsmPropertyBag *property_bag,
+ LsmPropertyManager *property_manager);
G_END_DECLS
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index 5371a7d..ac85261 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -90,6 +90,7 @@ lsm_svg_circle_element_init (LsmSvgCircleElement *self)
static void
lsm_svg_circle_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgCircleElement class */
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 26299b2..cdb37a4 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -53,13 +53,16 @@ lsm_svg_element_child_changed (LsmDomNode *parent, LsmDomNode *child)
static void
lsm_svg_element_set_attribute (LsmDomElement *self, const char* name, const char *value)
{
- LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS(self);
+ LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_GET_CLASS (self);
+ LsmSvgElement *s_element = LSM_SVG_ELEMENT (self);
lsm_debug ("[LsmSvgElement::set_attribute] node = %s, name = %s, value = %s",
lsm_dom_node_get_node_name (LSM_DOM_NODE (self)), name, value);
lsm_dom_attribute_map_set_attribute (s_element_class->attributes, self,
name, value);
+
+ lsm_svg_property_bag_set_property (&s_element->property_bag, name, value);
}
const char *
@@ -220,6 +223,15 @@ lsm_svg_element_init (LsmSvgElement *element)
static void
lsm_svg_element_finalize (GObject *object)
{
+ LsmSvgElement *svg_element = LSM_SVG_ELEMENT (object);
+ char *string;
+
+ string = lsm_svg_property_bag_serialize (&svg_element->property_bag);
+ lsm_debug ("%s", string);
+ g_free (string);
+
+ lsm_svg_property_bag_clean (&svg_element->property_bag);
+
parent_class->finalize (object);
}
diff --git a/src/lsmsvgelement.h b/src/lsmsvgelement.h
index 0a877c3..42fc3a1 100644
--- a/src/lsmsvgelement.h
+++ b/src/lsmsvgelement.h
@@ -44,6 +44,8 @@ typedef struct _LsmSvgElementClass LsmSvgElementClass;
struct _LsmSvgElement {
LsmDomElement element;
+ LsmPropertyBag property_bag;
+
LsmDomAttribute id;
/* View */
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index 17f7783..233b539 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -91,6 +91,7 @@ lsm_svg_ellipse_element_init (LsmSvgEllipseElement *self)
static void
lsm_svg_ellipse_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgEllipseElement class */
diff --git a/src/lsmsvggraphic.c b/src/lsmsvggraphic.c
index 75ec2c5..4974377 100644
--- a/src/lsmsvggraphic.c
+++ b/src/lsmsvggraphic.c
@@ -253,6 +253,7 @@ lsm_svg_graphic_init (LsmSvgGraphic *self)
static void
lsm_svg_graphic_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgGraphic class */
diff --git a/src/lsmsvgimageelement.c b/src/lsmsvgimageelement.c
index 61057fd..0b4b2db 100644
--- a/src/lsmsvgimageelement.c
+++ b/src/lsmsvgimageelement.c
@@ -172,6 +172,8 @@ lsm_svg_image_element_finalize (GObject *gobject)
if (image->pixbuf != NULL)
g_object_unref (image->pixbuf);
+
+ parent_class->finalize (gobject);
}
/* LsmSvgImageElement class */
diff --git a/src/lsmsvglineargradientelement.c b/src/lsmsvglineargradientelement.c
index 2fd37cf..9301706 100644
--- a/src/lsmsvglineargradientelement.c
+++ b/src/lsmsvglineargradientelement.c
@@ -110,6 +110,7 @@ lsm_svg_linear_gradient_element_init (LsmSvgLinearGradientElement *self)
static void
lsm_svg_linear_gradient_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgLinearGradientElement class */
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index e7e55d1..7514e5f 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -63,6 +63,7 @@ lsm_svg_path_element_init (LsmSvgPathElement *self)
static void
lsm_svg_path_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgPathElement class */
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index a219369..7c3279a 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -126,6 +126,7 @@ lsm_svg_radial_gradient_element_init (LsmSvgRadialGradientElement *self)
static void
lsm_svg_radial_gradient_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgRadialGradientElement class */
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index b039e9c..53a30b3 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -130,6 +130,7 @@ lsm_svg_rect_element_init (LsmSvgRectElement *self)
static void
lsm_svg_rect_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgRectElement class */
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 8e98709..09a3717 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -20,7 +20,693 @@
*/
#include <lsmsvgstyle.h>
+#include <lsmsvgcolors.h>
+#include <lsmsvgutils.h>
#include <string.h>
+#include <math.h>
+
+static const LsmPropertyClass lsm_svg_property_class = {
+ .size = sizeof (LsmProperty)
+};
+
+static void
+lsm_svg_double_property_from_text (LsmProperty *property, const char *value)
+{
+ LsmSvgDoubleProperty *svg_double = (LsmSvgDoubleProperty *) property;
+
+ svg_double->value = g_strtod (value, NULL);
+}
+
+char *
+lsm_svg_double_property_to_text (LsmProperty *property)
+{
+ LsmSvgDoubleProperty *svg_double = (LsmSvgDoubleProperty *) property;
+
+ return g_strdup_printf ("%g", svg_double->value);
+}
+
+static const LsmPropertyClass lsm_svg_double_property_class = {
+ .size = sizeof (LsmSvgDoubleProperty),
+ .from_text = lsm_svg_double_property_from_text,
+ .to_text = lsm_svg_double_property_to_text
+};
+
+static void
+lsm_svg_length_property_from_text (LsmProperty *property, const char *value)
+{
+ LsmSvgLengthProperty *svg_length = (LsmSvgLengthProperty *) property;
+ char *length_type_str;
+
+ svg_length->length.value_unit = g_strtod (value, &length_type_str);
+ svg_length->length.type = lsm_svg_length_type_from_string (length_type_str);
+}
+
+char *
+lsm_svg_length_property_to_text (LsmProperty *property)
+{
+ LsmSvgLengthProperty *svg_length = (LsmSvgLengthProperty *) property;
+
+ return g_strdup_printf ("%g%s",
+ svg_length->length.value_unit,
+ lsm_svg_length_type_to_string (svg_length->length.type));
+}
+
+static const LsmPropertyClass lsm_svg_length_property_class = {
+ .size = sizeof (LsmSvgLengthProperty),
+ .from_text = lsm_svg_length_property_from_text,
+ .to_text = lsm_svg_length_property_to_text
+};
+
+static void
+_init_matrix (LsmSvgMatrix *matrix, LsmSvgTransformType transform, unsigned int n_values, double values[])
+{
+ switch (transform) {
+ case LSM_SVG_TRANSFORM_TYPE_SCALE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_scale (matrix, values[0], values[0]);
+ return;
+ } else if (n_values == 2) {
+ lsm_svg_matrix_init_scale (matrix, values[0], values[1]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_TRANSLATE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_translate (matrix, values[0], values[0]);
+ return;
+ } else if (n_values == 2) {
+ lsm_svg_matrix_init_translate (matrix, values[0], values[1]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_MATRIX:
+ if (n_values == 6) {
+ lsm_svg_matrix_init (matrix,
+ values[0], values[1],
+ values[2], values[3],
+ values[4], values[5]);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_ROTATE:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_rotate (matrix, values[0] * M_PI / 180.0);
+ return;
+ } else if (n_values == 3) {
+ LsmSvgMatrix matrix_b;
+
+ lsm_svg_matrix_init_translate (matrix, values[1], values[2]);
+ lsm_svg_matrix_init_rotate (&matrix_b, values[0] * M_PI / 180.0);
+ lsm_svg_matrix_multiply (matrix, &matrix_b, matrix);
+ lsm_svg_matrix_init_translate (&matrix_b, -values[1], -values[2]);
+ lsm_svg_matrix_multiply (matrix, &matrix_b, matrix);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_SKEW_X:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_skew_x (matrix, values[0] * M_PI / 180.0);
+ return;
+ }
+ break;
+ case LSM_SVG_TRANSFORM_TYPE_SKEW_Y:
+ if (n_values == 1) {
+ lsm_svg_matrix_init_skew_y (matrix, values[0] * M_PI / 180.0);
+ return;
+ }
+ default:
+ break;
+ }
+
+ lsm_svg_matrix_init_identity (matrix);
+}
+
+static void
+lsm_svg_transform_property_from_text (LsmProperty *property, const char *value)
+{
+ LsmSvgTransformProperty *svg_transform = (LsmSvgTransformProperty *) property;
+ char *string;
+
+ string = (char *) value;
+
+ lsm_svg_matrix_init_identity (&svg_transform->matrix);
+
+ while (*string != '\0') {
+ LsmSvgTransformType transform;
+ double values[6];
+
+ lsm_svg_str_skip_spaces (&string);
+
+ if (strncmp (string, "translate", 9) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_TRANSLATE;
+ string += 9;
+ } else if (strncmp (string, "scale", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SCALE;
+ string += 5;
+ } else if (strncmp (string, "rotate", 6) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_ROTATE;
+ string += 6;
+ } else if (strncmp (string, "matrix", 6) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_MATRIX;
+ string += 6;
+ } else if (strncmp (string, "skewX", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SKEW_X;
+ string += 5;
+ } else if (strncmp (string, "skewY", 5) == 0) {
+ transform = LSM_SVG_TRANSFORM_TYPE_SKEW_Y;
+ string += 5;
+ } else
+ break;
+
+ lsm_svg_str_skip_spaces (&string);
+
+ if (*string == '(') {
+ unsigned int n_values = 0;
+
+ string++;
+
+ while (*string != ')' && *string != '\0' && n_values < 6) {
+ lsm_svg_str_skip_comma_and_spaces (&string);
+
+ if (!lsm_svg_str_parse_double (&string, &values[n_values]))
+ break;
+
+ n_values++;
+ }
+
+ lsm_svg_str_skip_comma_and_spaces (&string);
+
+ if (*string == ')') {
+ LsmSvgMatrix matrix;
+
+ string++;
+
+ _init_matrix (&matrix, transform, n_values, values);
+
+ lsm_svg_matrix_multiply (&svg_transform->matrix, &matrix, &svg_transform->matrix);
+ }
+ }
+ }
+}
+
+char *
+lsm_svg_transform_property_to_text (LsmProperty *property)
+{
+ LsmSvgTransformProperty *svg_transform = (LsmSvgTransformProperty *) property;
+
+ /* TODO smarter serialization, checking for zeros */
+ return g_strdup_printf ("matrix(%g,%g,%g,%g,%g,%g)",
+ svg_transform->matrix.a,
+ svg_transform->matrix.b,
+ svg_transform->matrix.c,
+ svg_transform->matrix.d,
+ svg_transform->matrix.e,
+ svg_transform->matrix.f);
+}
+
+static const LsmPropertyClass lsm_svg_transform_property_class = {
+ .size = sizeof (LsmSvgTransformProperty),
+ .from_text = lsm_svg_transform_property_from_text,
+ .to_text = lsm_svg_transform_property_to_text
+};
+
+static char *
+_parse_color (char *string,
+ LsmSvgColor *svg_color,
+ gboolean *is_color_set)
+{
+ unsigned int color = 0;
+ *is_color_set = FALSE;
+
+ lsm_svg_str_skip_spaces (&string);
+
+ if (g_strcmp0 (string, "currentColor") == 0) {
+ svg_color->red = -1.0;
+ svg_color->green = 1.0;
+ svg_color->blue = 1.0;
+
+ *is_color_set = TRUE;
+
+ string += 12; /* strlen ("current_color") */
+
+ return string;
+ }
+
+ if (*string == '#') {
+ int value, i;
+ string++;
+
+ for (i = 0; i < 6; i++) {
+ if (*string >= '0' && *string <= '9')
+ value = *string - '0';
+ else if (*string >= 'A' && *string <= 'F')
+ value = *string - 'A' + 10;
+ else if (*string >= 'a' && *string <= 'f')
+ value = *string - 'a' + 10;
+ else
+ break;
+
+ color = (color << 4) + value;
+ string++;
+ }
+
+ if (i == 3) {
+ color = ((color & 0xf00) << 8) | ((color & 0x0f0) << 4) | (color & 0x00f);
+ color |= color << 4;
+ } else if (i != 6)
+ color = 0;
+
+ *is_color_set = TRUE;
+ } else if (strncmp (string, "rgb(", 4) == 0) {
+ int i;
+ double value;
+
+
+ string += 4; /* strlen ("rgb(") */
+
+ for (i = 0; i < 3; i++) {
+ if (!lsm_svg_str_parse_double (&string, &value))
+ break;
+
+ if (*string == '%') {
+ value = value * 255.0 / 100.0;
+ string++;
+ }
+
+ if (i < 2)
+ lsm_svg_str_skip_comma_and_spaces (&string);
+
+ color = (color << 8) + (int) (0.5 + CLAMP (value, 0.0, 255.0));
+ }
+
+ lsm_svg_str_skip_spaces (&string);
+
+ if (*string != ')' || i != 3)
+ color = 0;
+
+ *is_color_set = TRUE;
+ } else if (g_strcmp0 (string, "none") == 0) {
+ *is_color_set = FALSE;
+ } else {
+ color = lsm_svg_color_from_string (string);
+
+ *is_color_set = TRUE;
+ }
+
+ svg_color->red = (double) ((color & 0xff0000) >> 16) / 255.0;
+ svg_color->green = (double) ((color & 0x00ff00) >> 8) / 255.0;
+ svg_color->blue = (double) (color & 0x0000ff) / 255.0;
+
+ return string;
+}
+
+static void
+lsm_svg_paint_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgPaintProperty *property = (LsmSvgPaintProperty *) abstract_property;
+ char *string;
+ gboolean is_color_set;
+
+ g_free (property->paint.uri);
+
+ string = (char *) value;
+
+ if (strncmp (string, "url(#", 5) == 0) {
+ unsigned int length;
+
+ string += 5;
+ length = 0;
+ while (string[length] != ')')
+ length++;
+ length++;
+
+ property->paint.uri = g_new (char, length);
+ if (property->paint.uri != NULL) {
+ memcpy (property->paint.uri, string, length - 1);
+ property->paint.uri[length - 1] = '\0';
+ }
+ string += length;
+ } else {
+ property->paint.uri = NULL;
+ }
+
+ string = _parse_color (string, &property->paint.color, &is_color_set);
+
+ if (is_color_set)
+ property->paint.type = property->paint.uri != NULL ?
+ LSM_SVG_PAINT_TYPE_URI_RGB_COLOR :
+ LSM_SVG_PAINT_TYPE_RGB_COLOR;
+ else
+ property->paint.type = property->paint.uri != NULL ?
+ LSM_SVG_PAINT_TYPE_URI :
+ LSM_SVG_PAINT_TYPE_NONE;
+}
+
+char *
+lsm_svg_paint_property_to_text (LsmProperty *abstract_property)
+{
+ LsmSvgPaintProperty *property = (LsmSvgPaintProperty *) abstract_property;
+
+ if (property->paint.color.red < 0.0 ||
+ property->paint.color.green < 0.0 ||
+ property->paint.color.blue < 0.0)
+ return g_strdup ("currentColor");
+
+ if (property->paint.uri != NULL)
+ g_strdup_printf ("url(#%s)", property->paint.uri);
+
+ return g_strdup_printf ("rgb(%g%%,%g%%,%g%%)",
+ 100.0 * property->paint.color.red,
+ 100.0 * property->paint.color.green,
+ 100.0 * property->paint.color.blue);
+}
+
+static const LsmPropertyClass lsm_svg_paint_property_class = {
+ .size = sizeof (LsmSvgPaintProperty),
+ .from_text = lsm_svg_paint_property_from_text,
+ .to_text = lsm_svg_paint_property_to_text
+};
+
+static void
+lsm_svg_fill_rule_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgFillRuleProperty *property = (LsmSvgFillRuleProperty *) abstract_property;
+
+ property->value = lsm_svg_fill_rule_from_string (value);
+}
+
+char *
+lsm_svg_fill_rule_property_to_text (LsmProperty *abstract_property)
+{
+ LsmSvgFillRuleProperty *property = (LsmSvgFillRuleProperty *) abstract_property;
+
+ return g_strdup (lsm_svg_fill_rule_to_string (property->value));
+}
+
+static const LsmPropertyClass lsm_svg_fill_rule_property_class = {
+ .size = sizeof (LsmSvgFillRuleProperty),
+ .from_text = lsm_svg_fill_rule_property_from_text,
+ .to_text = lsm_svg_fill_rule_property_to_text
+};
+
+static void
+lsm_svg_line_join_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgLineJoinProperty *property = (LsmSvgLineJoinProperty *) abstract_property;
+
+ property->value = lsm_svg_line_join_from_string (value);
+}
+
+char *
+lsm_svg_line_join_property_to_text (LsmProperty *abstract_property)
+{
+ LsmSvgLineJoinProperty *property = (LsmSvgLineJoinProperty *) abstract_property;
+
+ return g_strdup (lsm_svg_line_join_to_string (property->value));
+}
+
+static const LsmPropertyClass lsm_svg_line_join_property_class = {
+ .size = sizeof (LsmSvgLineJoinProperty),
+ .from_text = lsm_svg_line_join_property_from_text,
+ .to_text = lsm_svg_line_join_property_to_text
+};
+
+static void
+lsm_svg_line_cap_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgLineCapProperty *property = (LsmSvgLineCapProperty *) abstract_property;
+
+ property->value = lsm_svg_line_cap_from_string (value);
+}
+
+static char *
+lsm_svg_line_cap_property_to_text (LsmProperty *abstract_property)
+{
+ LsmSvgLineCapProperty *property = (LsmSvgLineCapProperty *) abstract_property;
+
+ return g_strdup (lsm_svg_line_cap_to_string (property->value));
+}
+
+static const LsmPropertyClass lsm_svg_line_cap_property_class = {
+ .size = sizeof (LsmSvgLineCapProperty),
+ .from_text = lsm_svg_line_cap_property_from_text,
+ .to_text = lsm_svg_line_cap_property_to_text
+};
+
+static void
+lsm_svg_dash_array_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgDashArrayProperty *property = (LsmSvgDashArrayProperty *) abstract_property;
+ char *string;
+ unsigned int n_dashes = 1;
+
+ string = (char *) value;
+
+ lsm_svg_dash_array_free (property->value);
+
+ if (strcmp (string, "none") == 0) {
+ property->value = (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+ } else {
+ char *iter = (char *) string;
+ unsigned int i;
+
+ while (*iter != '\0') {
+ if (*iter == ',')
+ n_dashes++;
+ iter++;
+ }
+
+ property->value = lsm_svg_dash_array_new (n_dashes);
+ if (property->value != &lsm_svg_dash_array_null) {
+ LsmSvgLength length;
+
+ iter = (char *)string;
+ lsm_svg_str_skip_spaces (&iter);
+
+ for (i = 0; i < n_dashes; i++) {
+ if (lsm_svg_str_parse_double (&iter, &length.value_unit)) {
+ length.type = lsm_svg_length_type_from_string (iter);
+ property->value->dashes[i] = length;
+ while (*iter != '\0' && *iter != ' ' && *iter != ',')
+ iter ++;
+ } else {
+ property->value->dashes[i].value_unit = 0.0;
+ property->value->dashes[i].value_unit = LSM_SVG_LENGTH_TYPE_NUMBER;
+ }
+ lsm_svg_str_skip_comma_and_spaces (&iter);
+ }
+ }
+ }
+}
+
+static char *
+lsm_svg_dash_array_property_to_text (LsmProperty *abstract_property)
+{
+ g_assert_not_reached ();
+}
+
+static void
+lsm_svg_dash_array_property_finalize (LsmProperty *abstract_property)
+{
+ LsmSvgDashArrayProperty *property = (LsmSvgDashArrayProperty *) abstract_property;
+
+ lsm_svg_dash_array_free (property->value);
+ property->value = NULL;
+}
+
+static const LsmPropertyClass lsm_svg_dash_array_property_class = {
+ .size = sizeof (LsmSvgDashArrayProperty),
+ .from_text = lsm_svg_dash_array_property_from_text,
+ .to_text = lsm_svg_dash_array_property_to_text,
+ .finalize = lsm_svg_dash_array_property_finalize
+};
+
+static void
+lsm_svg_color_property_from_text (LsmProperty *abstract_property, const char *value)
+{
+ LsmSvgColorProperty *property = (LsmSvgColorProperty *) abstract_property;
+ char *string;
+ gboolean is_color_set;
+
+ string = (char *) value;
+
+ _parse_color (string, &property->value, &is_color_set);
+}
+
+char *
+lsm_svg_color_property_to_text (LsmProperty *abstract_property)
+{
+ LsmSvgColorProperty *property = (LsmSvgColorProperty *) abstract_property;
+
+ return g_strdup_printf ("rgb(%g%%,%g%%,%g%%)",
+ 100.0 * property->value.red,
+ 100.0 * property->value.green,
+ 100.0 * property->value.blue);
+}
+
+static const LsmPropertyClass lsm_svg_color_property_class = {
+ .size = sizeof (LsmSvgColorProperty),
+ .from_text = lsm_svg_color_property_from_text,
+ .to_text = lsm_svg_color_property_to_text
+};
+
+static const LsmPropertyInfos lsm_svg_property_infos[] = {
+ {
+ .name = "x",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, x),
+ .property_class = &lsm_svg_length_property_class
+ },
+ {
+ .name = "y",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, y),
+ .property_class = &lsm_svg_length_property_class
+ },
+ {
+ .name = "opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, group_opacity),
+ .property_class = &lsm_svg_double_property_class
+ },
+ {
+ .name = "transform",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, transform),
+ .property_class = &lsm_svg_transform_property_class
+ },
+ {
+ .name = "fill",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, fill.paint),
+ .property_class = &lsm_svg_paint_property_class
+ },
+ {
+ .name = "fill-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, fill.opacity),
+ .property_class = &lsm_svg_double_property_class
+ },
+ {
+ .name = "fill-rule",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, fill.rule),
+ .property_class = &lsm_svg_fill_rule_property_class
+ },
+ {
+ .name = "stroke",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.paint),
+ .property_class = &lsm_svg_paint_property_class
+ },
+ {
+ .name = "stroke-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.opacity),
+ .property_class = &lsm_svg_double_property_class
+ },
+ {
+ .name = "stroke-width",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.width),
+ .property_class = &lsm_svg_length_property_class
+ },
+ {
+ .name = "stroke-linejoin",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.line_join),
+ .property_class = &lsm_svg_line_join_property_class
+ },
+ {
+ .name = "stroke-linecap",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.line_cap),
+ .property_class = &lsm_svg_line_cap_property_class
+ },
+ {
+ .name = "stroke-miterlimit",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.miter_limit),
+ .property_class = &lsm_svg_double_property_class
+ },
+ {
+ .name = "stroke-dashoffset",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.dash_offset),
+ .property_class = &lsm_svg_length_property_class
+ },
+ {
+ .name = "stroke-dasharray",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, stroke.dash_array),
+ .property_class = &lsm_svg_dash_array_property_class
+ },
+ {
+ .name = "font-family",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, text.font_family),
+ .property_class = &lsm_svg_property_class
+ },
+ {
+ .name = "font-size",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, text.font_size),
+ .property_class = &lsm_svg_length_property_class
+ },
+ {
+ .name = "clip-path",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, clip.url),
+ .property_class = &lsm_svg_property_class
+ },
+ {
+ .name = "clip-rule",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, clip.rule),
+ .property_class = &lsm_svg_fill_rule_property_class
+ },
+ {
+ .name = "mask",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, mask.url),
+ .property_class = &lsm_svg_property_class
+ },
+ {
+ .name = "stop-color",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, gradient_stop.color),
+ .property_class = &lsm_svg_color_property_class
+ },
+ {
+ .name = "stop-opacity",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyleNew, gradient_stop.opacity),
+ .property_class = &lsm_svg_double_property_class
+ }
+};
+
+static LsmPropertyManager *
+lsm_svg_get_property_manager (void)
+{
+ static LsmPropertyManager *manager = NULL;
+
+ if (G_LIKELY (manager != NULL))
+ return manager;
+
+ manager = lsm_property_manager_new (G_N_ELEMENTS (lsm_svg_property_infos), lsm_svg_property_infos);
+
+ return manager;
+}
+
+void
+lsm_svg_property_bag_set_property (LsmPropertyBag *property_bag, const char *name, const char *value)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ lsm_property_bag_set_property (property_bag, property_manager, name, value);
+}
+
+const char *
+lsm_svg_property_bag_get_property (LsmPropertyBag *property_bag, const char *name)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ return lsm_property_bag_get_property (property_bag, property_manager, name);
+}
+
+void
+lsm_svg_property_bag_clean (LsmPropertyBag *property_bag)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ lsm_property_bag_clean (property_bag, property_manager);
+}
+
+char *
+lsm_svg_property_bag_serialize (LsmPropertyBag *property_bag)
+{
+ LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
+
+ return lsm_property_bag_serialize (property_bag, property_manager);
+}
LsmSvgStyle *
lsm_svg_style_new (void)
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index ccd0c37..da8ff92 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -22,11 +22,108 @@
#ifndef LSM_SVG_STYLE_H
#define LSM_SVG_STYLE_H
+#include <lsmproperties.h>
#include <lsmsvg.h>
#include <lsmsvgattributebags.h>
G_BEGIN_DECLS
+typedef struct {
+ LsmProperty base;
+ double value;
+} LsmSvgDoubleProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLength length;
+} LsmSvgLengthProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgPaint paint;
+} LsmSvgPaintProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgColor value;
+} LsmSvgColorProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgMatrix matrix;
+} LsmSvgTransformProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgFillRule value;
+} LsmSvgFillRuleProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLineJoin value;
+} LsmSvgLineJoinProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgLineCap value;
+} LsmSvgLineCapProperty;
+
+typedef struct {
+ LsmProperty base;
+ LsmSvgDashArray *value;
+} LsmSvgDashArrayProperty;
+
+typedef struct _LsmSvgStyleNew {
+ LsmSvgLengthProperty * x;
+ LsmSvgLengthProperty * y;
+
+ LsmSvgDoubleProperty * group_opacity;
+ LsmSvgTransformProperty * transform;
+
+ struct {
+ LsmSvgPaintProperty * paint;
+ LsmSvgDoubleProperty * opacity;
+ LsmSvgFillRuleProperty * rule;
+ } fill;
+
+ struct {
+ LsmSvgPaintProperty * paint;
+ LsmSvgDoubleProperty * opacity;
+ LsmSvgLengthProperty * width;
+ LsmSvgLineJoinProperty * line_join;
+ LsmSvgLineCapProperty * line_cap;
+ LsmSvgDoubleProperty * miter_limit;
+ LsmSvgLengthProperty * dash_offset;
+ LsmSvgDashArrayProperty * dash_array;
+ } stroke;
+
+ struct {
+ LsmProperty * font_family;
+ LsmSvgLengthProperty * font_size;
+ } text;
+
+ struct {
+ LsmProperty * url;
+ LsmSvgFillRuleProperty * rule;
+ } clip;
+
+ struct {
+ LsmProperty * url;
+ } mask;
+
+ struct {
+ LsmSvgColorProperty * color;
+ LsmSvgDoubleProperty * opacity;
+ } gradient_stop;
+} LsmSvgStyleNew;
+
+void lsm_svg_property_bag_set_property (LsmPropertyBag *property_bag,
+ const char *name, const char *value);
+const char * lsm_svg_property_bag_get_property (LsmPropertyBag *property_bag,
+ const char *name);
+void lsm_svg_property_bag_clean (LsmPropertyBag *property_bag);
+char * lsm_svg_property_bag_serialize (LsmPropertyBag *property_bag);
+
struct _LsmSvgStyle {
LsmBox viewport;
LsmSvgColor color;
diff --git a/src/lsmsvgsvgelement.c b/src/lsmsvgsvgelement.c
index be01e75..f009949 100644
--- a/src/lsmsvgsvgelement.c
+++ b/src/lsmsvgsvgelement.c
@@ -229,6 +229,8 @@ lsm_svg_svg_element_finalize (GObject *object)
LsmSvgSvgElement *svg_element = LSM_SVG_SVG_ELEMENT (object);
lsm_svg_style_free (svg_element->default_style);
+
+ parent_class->finalize (object);
}
/* LsmSvgSvgElement class */
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index f89c44e..4bfe73b 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -102,6 +102,7 @@ lsm_svg_text_element_init (LsmSvgTextElement *self)
static void
lsm_svg_text_element_finalize (GObject *object)
{
+ parent_class->finalize (object);
}
/* LsmSvgTextElement class */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]