[lasem] svg_gradient: support for href.



commit 3b1b289d01ef377b352f00b6f55b5a256ea954be
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Fri Aug 13 00:40:07 2010 +0200

    svg_gradient: support for href.

 src/Makefile.am                   |    6 +-
 src/lsmsvg.h                      |    1 -
 src/lsmsvgelement.c               |    6 +-
 src/lsmsvggradientelement.c       |  132 ------------------------
 src/lsmsvggradientelement.h       |   61 -----------
 src/lsmsvglineargradientelement.c |  186 +++++++++++++++++++++++++++++-----
 src/lsmsvglineargradientelement.h |   20 +++--
 src/lsmsvgradialgradientelement.c |  201 +++++++++++++++++++++++++++++++-----
 src/lsmsvgradialgradientelement.h |   12 ++-
 src/lsmsvgview.c                  |    8 +-
 10 files changed, 368 insertions(+), 265 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b35fb4a..3669113 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -99,7 +99,6 @@ liblasem_ LASEM_API_VERSION@_la_SOURCES =				\
 	lsmsvgpathelement.c			\
 	lsmsvgtextelement.c			\
 	lsmsvgtspanelement.c			\
-	lsmsvggradientelement.c			\
 	lsmsvglineargradientelement.c		\
 	lsmsvgradialgradientelement.c		\
 	lsmsvgstopelement.c			\
@@ -187,7 +186,6 @@ LASEM_HDRS = \
 	lsmsvgpolygonelement.h			\
 	lsmsvgtextelement.h			\
 	lsmsvgtspanelement.h			\
-	lsmsvggradientelement.h			\
 	lsmsvglineargradientelement.h		\
 	lsmsvgradialgradientelement.h		\
 	lsmsvgstopelement.h			\
@@ -238,10 +236,10 @@ Lasem_0_4_gir_FILES = $(addprefix $(srcdir)/,$(introspection_files))
 
 INTROSPECTION_GIRS += Lasem- LASEM_API_VERSION@.gir
 
-girdir = $(datadir)/gir-1.0
+girdir = $(datadir)/gir-1.1
 dist_gir_DATA = $(INTROSPECTION_GIRS)
 
-typelibdir = $(libdir)/girepositry-1.0
+typelibdir = $(libdir)/girepositry-1.1
 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
 
 CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
diff --git a/src/lsmsvg.h b/src/lsmsvg.h
index a6b61d5..d9c1639 100644
--- a/src/lsmsvg.h
+++ b/src/lsmsvg.h
@@ -47,7 +47,6 @@ typedef struct _LsmSvgPolygonElement LsmSvgPolygonElement;
 typedef struct _LsmSvgPathElement LsmSvgPathElement;
 typedef struct _LsmSvgTextElement LsmSvgTextElement;
 typedef struct _LsmSvgTspanElement LsmSvgTspanElement;
-typedef struct _LsmSvgGradientElement LsmSvgGradientElement;
 typedef struct _LsmSvgLinearGradientElement LsmSvgLinearGradientElement;
 typedef struct _LsmSvgRadialGradientElement LsmSvgRadialGradientElement;
 typedef struct _LsmSvgStopElement LsmSvgStopElement;
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 3995b00..cca6411 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -26,7 +26,8 @@
 #include <lsmdomdocument.h>
 #include <lsmsvgelement.h>
 #include <lsmsvgpatternelement.h>
-#include <lsmsvggradientelement.h>
+#include <lsmsvgradialgradientelement.h>
+#include <lsmsvglineargradientelement.h>
 #include <lsmsvgclippathelement.h>
 #include <lsmsvgmarkerelement.h>
 #include <lsmsvgmaskelement.h>
@@ -176,7 +177,8 @@ void
 lsm_svg_element_force_render (LsmSvgElement *element, LsmSvgView *view)
 {
 	g_return_if_fail (LSM_IS_SVG_PATTERN_ELEMENT (element) ||
-			  LSM_IS_SVG_GRADIENT_ELEMENT (element) ||
+			  LSM_IS_SVG_RADIAL_GRADIENT_ELEMENT (element) ||
+			  LSM_IS_SVG_LINEAR_GRADIENT_ELEMENT (element) ||
 			  LSM_IS_SVG_MASK_ELEMENT (element) ||
 			  LSM_IS_SVG_CLIP_PATH_ELEMENT (element) ||
 			  LSM_IS_SVG_MARKER_ELEMENT (element));
diff --git a/src/lsmsvglineargradientelement.c b/src/lsmsvglineargradientelement.c
index ac92e72..5e7cc6d 100644
--- a/src/lsmsvglineargradientelement.c
+++ b/src/lsmsvglineargradientelement.c
@@ -22,9 +22,30 @@
 
 #include <lsmsvglineargradientelement.h>
 #include <lsmsvgview.h>
+#include <lsmdomdocument.h>
 #include <lsmdebug.h>
 #include <stdio.h>
 
+typedef struct {
+	LsmSvgLength x1;
+	LsmSvgLength y1;
+	LsmSvgLength x2;
+	LsmSvgLength y2;
+	LsmSvgMatrix transform;
+	LsmSvgPatternUnits units;
+	LsmSvgSpreadMethod spread_method;
+} LsmSvgLinearGradientElementAttributes;
+
+static const LsmSvgLinearGradientElementAttributes default_attributes = {
+	.x1 = { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.y1 = { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.x2 = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.y1 = { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.transform = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY},
+	.units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX,
+	.spread_method = LSM_SVG_SPREAD_METHOD_PAD
+};
+
 static GObjectClass *parent_class;
 
 /* GdomNode implementation */
@@ -35,17 +56,97 @@ lsm_svg_linear_gradient_element_get_node_name (LsmDomNode *node)
 	return "linearGradient";
 }
 
-/* GLinearGradientElement implementation */
+/* LsmSvgElement implementation */
+
+static LsmSvgLinearGradientElement *
+lsm_svg_linear_gradient_element_inherit_referenced (LsmDomDocument *owner,
+					    LsmSvgLinearGradientElement *gradient,
+					    LsmSvgLinearGradientElementAttributes *attributes)
+{
+	LsmSvgLinearGradientElement *referenced_gradient = gradient;
+	LsmDomElement *element;
+
+	if (lsm_attribute_is_defined (&gradient->href)) {
+		char *id;
+
+		id = gradient->href.value;
+		if (id == NULL)
+			return NULL;
+		if (*id == '#')
+			id++;
+
+		element = lsm_dom_document_get_element_by_id (owner, id);
+		if (LSM_IS_SVG_LINEAR_GRADIENT_ELEMENT (element)) {
+			lsm_debug ("render",
+				   "[LsmSvgLinearGradientElement::inherit_attributes]"
+				   " Found referenced element '%s'", id);
+
+			referenced_gradient = lsm_svg_linear_gradient_element_inherit_referenced
+				(owner,
+				 LSM_SVG_LINEAR_GRADIENT_ELEMENT (element),
+				 attributes);
+		} else {
+			lsm_debug ("render",
+				   "[LsmSvgLinearGradientElement::inherit_attributes]"
+				   " Referenced element '%s' not found", id);
+			referenced_gradient = NULL;
+		}
+	}
+
+	if (lsm_attribute_is_defined (&gradient->x1.base))
+		attributes->x1 = gradient->x1.length;
+	if (lsm_attribute_is_defined (&gradient->y1.base))
+		attributes->y1 = gradient->y1.length;
+	if (lsm_attribute_is_defined (&gradient->x1.base))
+		attributes->x2 = gradient->x2.length;
+	if (lsm_attribute_is_defined (&gradient->y2.base))
+		attributes->y2 = gradient->y2.length;
+	if (lsm_attribute_is_defined (&gradient->transform.base))
+		attributes->transform = gradient->transform.matrix;
+	if (lsm_attribute_is_defined (&gradient->units.base))
+		attributes->units = gradient->units.value;
+	if (lsm_attribute_is_defined (&gradient->spread_method.base))
+		attributes->spread_method = gradient->spread_method.value;
+
+	return referenced_gradient;
+}
 
 static void
-lsm_svg_linear_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_linear_gradient_element_render (LsmSvgElement *self, LsmSvgView *view)
 {
-	LsmSvgLinearGradientElement *linear = LSM_SVG_LINEAR_GRADIENT_ELEMENT (self);
+	LsmSvgLinearGradientElement *gradient = LSM_SVG_LINEAR_GRADIENT_ELEMENT (self);
+	LsmSvgLinearGradientElement *referenced_gradient;
 	gboolean is_object_bounding_box;
 	double x1, x2, y1, y2;
 
-	is_object_bounding_box = (LSM_SVG_GRADIENT_ELEMENT (self)->units.value ==
-				  LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+	if (!gradient->enable_rendering)
+		return;
+
+	gradient->enable_rendering = FALSE;
+
+	if (lsm_attribute_is_defined (&gradient->href)) {
+		LsmSvgLinearGradientElementAttributes attributes;
+		LsmDomDocument *owner;
+		attributes = default_attributes;
+
+		owner = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
+
+		referenced_gradient = lsm_svg_linear_gradient_element_inherit_referenced (owner, gradient, &attributes);
+
+		gradient->x1.length = attributes.x1;
+		gradient->y1.length = attributes.y1;
+		gradient->x2.length = attributes.x2;
+		gradient->y2.length = attributes.y2;
+		gradient->transform.matrix = attributes.transform;
+		gradient->units.value = attributes.units;
+		gradient->spread_method.value = attributes.spread_method;
+	} else
+		referenced_gradient = gradient;
+
+	if (referenced_gradient == NULL)
+		return;
+
+	is_object_bounding_box = (gradient->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
 
 	if (is_object_bounding_box) {
 		LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
@@ -53,10 +154,10 @@ lsm_svg_linear_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView
 		lsm_svg_view_push_viewbox (view, &viewbox);
 	}
 
-	x1 = lsm_svg_view_normalize_length (view, &linear->x1.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
-	y1 = lsm_svg_view_normalize_length (view, &linear->y1.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
-	x2 = lsm_svg_view_normalize_length (view, &linear->x2.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
-	y2 = lsm_svg_view_normalize_length (view, &linear->y2.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	x1 = lsm_svg_view_normalize_length (view, &gradient->x1.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	y1 = lsm_svg_view_normalize_length (view, &gradient->y1.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	x2 = lsm_svg_view_normalize_length (view, &gradient->x2.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	y2 = lsm_svg_view_normalize_length (view, &gradient->y2.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
 
 	lsm_debug ("render", "[LsmSvgLinearGradientElement::render] Create linear %g, %g, %g, %g",
 		    x1, y1, x2, y2);
@@ -65,6 +166,19 @@ lsm_svg_linear_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView
 		lsm_svg_view_pop_viewbox (view);
 
 	lsm_svg_view_create_linear_gradient (view, x1, y1, x2, y2);
+
+	lsm_svg_view_set_gradient_properties (view,
+					      gradient->spread_method.value,
+					      gradient->units.value,
+					      &gradient->transform.matrix);
+
+	LSM_SVG_ELEMENT_CLASS (parent_class)->render (LSM_SVG_ELEMENT (referenced_gradient), view);
+}
+
+static void
+lsm_svg_linear_gradient_element_enable_rendering (LsmSvgElement *element)
+{
+	LSM_SVG_LINEAR_GRADIENT_ELEMENT (element)->enable_rendering = TRUE;
 }
 
 /* LsmSvgLinearGradientElement implementation */
@@ -75,16 +189,18 @@ lsm_svg_linear_gradient_element_new (void)
 	return g_object_new (LSM_TYPE_SVG_LINEAR_GRADIENT_ELEMENT, NULL);
 }
 
-static const LsmSvgLength x1_y1_y2_default = 	{ .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
-static const LsmSvgLength x2_default =		{ .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
-
 static void
 lsm_svg_linear_gradient_element_init (LsmSvgLinearGradientElement *self)
 {
-	self->x1.length = x1_y1_y2_default;
-	self->y1.length = x1_y1_y2_default;
-	self->x2.length = x2_default;
-	self->y2.length = x1_y1_y2_default;
+	self->enable_rendering = FALSE;
+
+	self->x1.length = default_attributes.x1;
+	self->y1.length = default_attributes.y1;
+	self->x2.length = default_attributes.x2;
+	self->y2.length = default_attributes.y2;
+	self->transform.matrix = default_attributes.transform;
+	self->units.value = default_attributes.units;
+	self->spread_method.value = default_attributes.spread_method;
 }
 
 static void
@@ -100,25 +216,48 @@ static const LsmAttributeInfos lsm_svg_linear_gradient_element_attribute_infos[]
 		.name = "x1",
 		.attribute_offset = offsetof (LsmSvgLinearGradientElement, x1),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &x1_y1_y2_default
+		.trait_default = &default_attributes.x1
 	},
 	{
 		.name = "y1",
 		.attribute_offset = offsetof (LsmSvgLinearGradientElement, y1),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &x1_y1_y2_default
+		.trait_default = &default_attributes.y1
 	},
 	{
 		.name = "x2",
 		.attribute_offset = offsetof (LsmSvgLinearGradientElement, x2),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &x2_default
+		.trait_default = &default_attributes.x2
 	},
 	{
 		.name = "y2",
 		.attribute_offset = offsetof (LsmSvgLinearGradientElement, y2),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &x1_y1_y2_default
+		.trait_default = &default_attributes.y2
+	},
+	{
+		.name = "gradientTransform",
+		.attribute_offset = offsetof (LsmSvgLinearGradientElement, transform),
+		.trait_class = &lsm_svg_matrix_trait_class,
+		.trait_default = &default_attributes.transform
+	},
+	{
+		.name = "gradientUnits",
+		.attribute_offset = offsetof (LsmSvgLinearGradientElement, units),
+		.trait_class = &lsm_svg_pattern_units_trait_class,
+		.trait_default = &default_attributes.units
+	},
+	{
+		.name = "spreadMethod",
+		.attribute_offset = offsetof (LsmSvgLinearGradientElement, spread_method),
+		.trait_class = &lsm_svg_spread_method_trait_class,
+		.trait_default = &default_attributes.spread_method
+	},
+	{
+		.name = "xlink:href",
+		.attribute_offset = offsetof (LsmSvgLinearGradientElement, href),
+		.trait_class = &lsm_null_trait_class
 	}
 };
 
@@ -128,7 +267,6 @@ lsm_svg_linear_gradient_element_class_init (LsmSvgLinearGradientElementClass *s_
 	GObjectClass *object_class = G_OBJECT_CLASS (s_svg_class);
 	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_svg_class);
 	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_svg_class);
-	LsmSvgGradientElementClass *s_gradient_class = LSM_SVG_GRADIENT_ELEMENT_CLASS (s_svg_class);
 
 	parent_class = g_type_class_peek_parent (s_svg_class);
 
@@ -138,13 +276,13 @@ lsm_svg_linear_gradient_element_class_init (LsmSvgLinearGradientElementClass *s_
 
 	s_element_class->category = LSM_SVG_ELEMENT_CATEGORY_GRADIENT;
 
+	s_element_class->render = lsm_svg_linear_gradient_element_render;
+	s_element_class->enable_rendering = lsm_svg_linear_gradient_element_enable_rendering;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_linear_gradient_element_attribute_infos),
 					      lsm_svg_linear_gradient_element_attribute_infos);
-
-	s_gradient_class->create_gradient = lsm_svg_linear_gradient_element_create_gradient;
 }
 
-G_DEFINE_TYPE (LsmSvgLinearGradientElement, lsm_svg_linear_gradient_element, LSM_TYPE_SVG_GRADIENT_ELEMENT)
+G_DEFINE_TYPE (LsmSvgLinearGradientElement, lsm_svg_linear_gradient_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvglineargradientelement.h b/src/lsmsvglineargradientelement.h
index 8801fae..202eb6e 100644
--- a/src/lsmsvglineargradientelement.h
+++ b/src/lsmsvglineargradientelement.h
@@ -24,7 +24,7 @@
 #define LSM_SVG_LINEAR_GRADIENT_ELEMENT_H
 
 #include <lsmsvg.h>
-#include <lsmsvggradientelement.h>
+#include <lsmsvgelement.h>
 
 G_BEGIN_DECLS
 
@@ -38,16 +38,22 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgLinearGradientElementClass LsmSvgLinearGradientElementClass;
 
 struct _LsmSvgLinearGradientElement {
-	LsmSvgGradientElement gradient;
+	LsmSvgElement element;
 
-	LsmSvgLengthAttribute	x1;
-	LsmSvgLengthAttribute	y1;
-	LsmSvgLengthAttribute	x2;
-	LsmSvgLengthAttribute	y2;
+	LsmSvgLengthAttribute x1;
+	LsmSvgLengthAttribute y1;
+	LsmSvgLengthAttribute x2;
+	LsmSvgLengthAttribute y2;
+	LsmSvgTransformAttribute transform;
+	LsmSvgPatternUnitsAttribute units;
+	LsmSvgSpreadMethodAtttribute spread_method;
+	LsmAttribute href;
+
+	gboolean enable_rendering;
 };
 
 struct _LsmSvgLinearGradientElementClass {
-	LsmSvgGradientElementClass  parent_class;
+	LsmSvgElementClass  parent_class;
 };
 
 GType lsm_svg_linear_gradient_element_get_type (void);
diff --git a/src/lsmsvgradialgradientelement.c b/src/lsmsvgradialgradientelement.c
index d554bc1..9c7a510 100644
--- a/src/lsmsvgradialgradientelement.c
+++ b/src/lsmsvgradialgradientelement.c
@@ -22,10 +22,33 @@
 
 #include <lsmsvgradialgradientelement.h>
 #include <lsmsvgview.h>
+#include <lsmdomdocument.h>
 #include <lsmdebug.h>
 #include <stdio.h>
 #include <math.h>
 
+typedef struct {
+	LsmSvgLength cx;
+	LsmSvgLength cy;
+	LsmSvgLength r;
+	LsmSvgLength fx;
+	LsmSvgLength fy;
+	LsmSvgMatrix transform;
+	LsmSvgPatternUnits units;
+	LsmSvgSpreadMethod spread_method;
+} LsmSvgRadialGradientElementAttributes;
+
+static const LsmSvgRadialGradientElementAttributes default_attributes = {
+	.cx = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.cy = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.r  = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE},
+	.fx = {.value_unit =  0.0, .type = LSM_SVG_LENGTH_TYPE_ERROR},
+	.fy = {.value_unit =  0.0, .type = LSM_SVG_LENGTH_TYPE_ERROR},
+	.transform = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY},
+	.units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX,
+	.spread_method = LSM_SVG_SPREAD_METHOD_PAD
+};
+
 static GObjectClass *parent_class;
 
 /* GdomNode implementation */
@@ -38,16 +61,101 @@ lsm_svg_radial_gradient_element_get_node_name (LsmDomNode *node)
 
 /* LsmSvgRadialGradientElement implementation */
 
+static LsmSvgRadialGradientElement *
+lsm_svg_radial_gradient_element_inherit_referenced (LsmDomDocument *owner,
+						    LsmSvgRadialGradientElement *gradient,
+						    LsmSvgRadialGradientElementAttributes *attributes)
+{
+	LsmSvgRadialGradientElement *referenced_gradient = gradient;
+	LsmDomElement *element;
+
+	if (lsm_attribute_is_defined (&gradient->href)) {
+		char *id;
+
+		id = gradient->href.value;
+		if (id == NULL)
+			return NULL;
+		if (*id == '#')
+			id++;
+
+		element = lsm_dom_document_get_element_by_id (owner, id);
+		if (LSM_IS_SVG_RADIAL_GRADIENT_ELEMENT (element)) {
+			lsm_debug ("render",
+				   "[LsmSvgRadialGradientElement::inherit_attributes]"
+				   " Found referenced element '%s'", id);
+
+			referenced_gradient = lsm_svg_radial_gradient_element_inherit_referenced
+				(owner,
+				 LSM_SVG_RADIAL_GRADIENT_ELEMENT (element),
+				 attributes);
+		} else {
+			lsm_debug ("render",
+				   "[LsmSvgRadialGradientElement::inherit_attributes]"
+				   " Referenced element '%s' not found", id);
+			referenced_gradient = NULL;
+		}
+	}
+
+	if (lsm_attribute_is_defined (&gradient->cx.base))
+		attributes->cx = gradient->cx.length;
+	if (lsm_attribute_is_defined (&gradient->cy.base))
+		attributes->cy = gradient->cy.length;
+	if (lsm_attribute_is_defined (&gradient->r.base))
+		attributes->r = gradient->r.length;
+	if (lsm_attribute_is_defined (&gradient->fx.base))
+		attributes->fx = gradient->fx.length;
+	if (lsm_attribute_is_defined (&gradient->fy.base))
+		attributes->fy = gradient->fy.length;
+	if (lsm_attribute_is_defined (&gradient->transform.base))
+		attributes->transform = gradient->transform.matrix;
+	if (lsm_attribute_is_defined (&gradient->units.base))
+		attributes->units = gradient->units.value;
+	if (lsm_attribute_is_defined (&gradient->spread_method.base))
+		attributes->spread_method = gradient->spread_method.value;
+
+	return referenced_gradient;
+}
+
 static void
-lsm_svg_radial_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView *view)
+lsm_svg_radial_gradient_element_render (LsmSvgElement *self, LsmSvgView *view)
 {
-	LsmSvgRadialGradientElement *radial = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
+	LsmSvgRadialGradientElement *gradient = LSM_SVG_RADIAL_GRADIENT_ELEMENT (self);
+	LsmSvgRadialGradientElement *referenced_gradient;
 	gboolean is_object_bounding_box;
 	double cx, cy, fx, fy, r;
 	double gradient_radius;
 
-	is_object_bounding_box = (LSM_SVG_GRADIENT_ELEMENT (self)->units.value ==
-				  LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+	if (!gradient->enable_rendering)
+		return;
+
+	gradient->enable_rendering = FALSE;
+
+	if (lsm_attribute_is_defined (&gradient->href)) {
+		LsmSvgRadialGradientElementAttributes attributes;
+		LsmDomDocument *owner;
+		attributes = default_attributes;
+
+		owner = lsm_dom_node_get_owner_document (LSM_DOM_NODE (self));
+
+		referenced_gradient = lsm_svg_radial_gradient_element_inherit_referenced (owner, gradient, &attributes);
+
+		gradient->cx.length = attributes.cy;
+		gradient->cy.length = attributes.cy;
+		gradient->r.length = attributes.r;
+		gradient->fx.length = attributes.fx;
+		gradient->fy.length = attributes.fy;
+		gradient->transform.matrix = attributes.transform;
+		gradient->units.value = attributes.units;
+		gradient->spread_method.value = attributes.spread_method;
+	} else
+		referenced_gradient = gradient;
+
+	if (referenced_gradient == NULL)
+		return;
+
+	is_object_bounding_box = (gradient->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+	g_message ("is_object_bounding_box = %s", is_object_bounding_box ? "TRUE" : "FALSE");
 
 	if (is_object_bounding_box) {
 		LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
@@ -55,17 +163,17 @@ lsm_svg_radial_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView
 		lsm_svg_view_push_viewbox (view, &viewbox);
 	}
 
-	cx = lsm_svg_view_normalize_length (view, &radial->cx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
-	cy = lsm_svg_view_normalize_length (view, &radial->cy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
-	r  = lsm_svg_view_normalize_length (view, &radial->r.length,  LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
+	cx = lsm_svg_view_normalize_length (view, &gradient->cx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	cy = lsm_svg_view_normalize_length (view, &gradient->cy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	r  = lsm_svg_view_normalize_length (view, &gradient->r.length,  LSM_SVG_LENGTH_DIRECTION_DIAGONAL);
 
-	if (lsm_attribute_is_defined (&radial->fx.base))
-		fx = lsm_svg_view_normalize_length (view, &radial->fx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	if (lsm_attribute_is_defined (&gradient->fx.base))
+		fx = lsm_svg_view_normalize_length (view, &gradient->fx.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
 	else
 		fx = cx;
 
-	if (lsm_attribute_is_defined (&radial->fy.base))
-		fy = lsm_svg_view_normalize_length (view, &radial->fy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	if (lsm_attribute_is_defined (&gradient->fy.base))
+		fy = lsm_svg_view_normalize_length (view, &gradient->fy.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
 	else
 		fy = cy;
 
@@ -87,6 +195,19 @@ lsm_svg_radial_gradient_element_create_gradient (LsmSvgElement *self, LsmSvgView
 		    cx, cy, r, fx, fy);
 
 	lsm_svg_view_create_radial_gradient (view, cx, cy, r, fx, fy);
+
+	lsm_svg_view_set_gradient_properties (view,
+					      gradient->spread_method.value,
+					      gradient->units.value,
+					      &gradient->transform.matrix);
+
+	LSM_SVG_ELEMENT_CLASS (parent_class)->render (LSM_SVG_ELEMENT (referenced_gradient), view);
+}
+
+static void
+lsm_svg_radial_gradient_element_enable_rendering (LsmSvgElement *element)
+{
+	LSM_SVG_RADIAL_GRADIENT_ELEMENT (element)->enable_rendering = TRUE;
 }
 
 /* LsmSvgRadialGradientElement implementation */
@@ -97,17 +218,19 @@ lsm_svg_radial_gradient_element_new (void)
 	return g_object_new (LSM_TYPE_SVG_RADIAL_GRADIENT_ELEMENT, NULL);
 }
 
-static const LsmSvgLength length_default = {.value_unit = 50.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
-static const LsmSvgLength unset_default  = {.value_unit =  0.0, .type = LSM_SVG_LENGTH_TYPE_ERROR};
-
 static void
 lsm_svg_radial_gradient_element_init (LsmSvgRadialGradientElement *self)
 {
-	self->cx.length = length_default;
-	self->cy.length = length_default;
-	self->r.length = length_default;
-	self->fx.length = unset_default;
-	self->fy.length = unset_default;
+	self->enable_rendering = FALSE;
+
+	self->cx.length = default_attributes.cx;
+	self->cy.length = default_attributes.cy;
+	self->r.length = default_attributes.r;
+	self->fx.length = default_attributes.fx;
+	self->fy.length = default_attributes.fy;
+	self->transform.matrix = default_attributes.transform;
+	self->units.value = default_attributes.units;
+	self->spread_method.value = default_attributes.spread_method;
 }
 
 static void
@@ -123,31 +246,54 @@ static const LsmAttributeInfos lsm_svg_radial_gradient_element_attribute_infos[]
 		.name = "cx",
 		.attribute_offset = offsetof (LsmSvgRadialGradientElement, cx),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &length_default
+		.trait_default = &default_attributes.cx
 	},
 	{
 		.name = "cy",
 		.attribute_offset = offsetof (LsmSvgRadialGradientElement, cy),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &length_default
+		.trait_default = &default_attributes.cy
 	},
 	{
 		.name = "r",
 		.attribute_offset = offsetof (LsmSvgRadialGradientElement, r),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &length_default
+		.trait_default = &default_attributes.r
 	},
 	{
 		.name = "fx",
 		.attribute_offset = offsetof (LsmSvgRadialGradientElement, fx),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &unset_default
+		.trait_default = &default_attributes.fx
 	},
 	{
 		.name = "fy",
 		.attribute_offset = offsetof (LsmSvgRadialGradientElement, fy),
 		.trait_class = &lsm_svg_length_trait_class,
-		.trait_default = &unset_default
+		.trait_default = &default_attributes.fy
+	},
+	{
+		.name = "gradientTransform",
+		.attribute_offset = offsetof (LsmSvgRadialGradientElement, transform),
+		.trait_class = &lsm_svg_matrix_trait_class,
+		.trait_default = &default_attributes.transform
+	},
+	{
+		.name = "gradientUnits",
+		.attribute_offset = offsetof (LsmSvgRadialGradientElement, units),
+		.trait_class = &lsm_svg_pattern_units_trait_class,
+		.trait_default = &default_attributes.units
+	},
+	{
+		.name = "spreadMethod",
+		.attribute_offset = offsetof (LsmSvgRadialGradientElement, spread_method),
+		.trait_class = &lsm_svg_spread_method_trait_class,
+		.trait_default = &default_attributes.spread_method
+	},
+	{
+		.name = "xlink:href",
+		.attribute_offset = offsetof (LsmSvgRadialGradientElement, href),
+		.trait_class = &lsm_null_trait_class
 	}
 };
 
@@ -157,7 +303,6 @@ lsm_svg_radial_gradient_element_class_init (LsmSvgRadialGradientElementClass *s_
 	GObjectClass *object_class = G_OBJECT_CLASS (s_svg_class);
 	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_svg_class);
 	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_svg_class);
-	LsmSvgGradientElementClass *s_gradient_class = LSM_SVG_GRADIENT_ELEMENT_CLASS (s_svg_class);
 
 	parent_class = g_type_class_peek_parent (s_svg_class);
 
@@ -167,13 +312,13 @@ lsm_svg_radial_gradient_element_class_init (LsmSvgRadialGradientElementClass *s_
 
 	s_element_class->category = LSM_SVG_ELEMENT_CATEGORY_GRADIENT;
 
+	s_element_class->render = lsm_svg_radial_gradient_element_render;
+	s_element_class->enable_rendering = lsm_svg_radial_gradient_element_enable_rendering;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_radial_gradient_element_attribute_infos),
 					      lsm_svg_radial_gradient_element_attribute_infos);
-
-	s_gradient_class->create_gradient = lsm_svg_radial_gradient_element_create_gradient;
 }
 
-G_DEFINE_TYPE (LsmSvgRadialGradientElement, lsm_svg_radial_gradient_element, LSM_TYPE_SVG_GRADIENT_ELEMENT)
+G_DEFINE_TYPE (LsmSvgRadialGradientElement, lsm_svg_radial_gradient_element, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgradialgradientelement.h b/src/lsmsvgradialgradientelement.h
index ea9a5f1..85bd60c 100644
--- a/src/lsmsvgradialgradientelement.h
+++ b/src/lsmsvgradialgradientelement.h
@@ -24,7 +24,7 @@
 #define LSM_SVG_RADIAL_GRADIENT_ELEMENT_H
 
 #include <lsmsvg.h>
-#include <lsmsvggradientelement.h>
+#include <lsmsvgelement.h>
 
 G_BEGIN_DECLS
 
@@ -38,17 +38,23 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgRadialGradientElementClass LsmSvgRadialGradientElementClass;
 
 struct _LsmSvgRadialGradientElement {
-	LsmSvgGradientElement gradient;
+	LsmSvgElement element;
 
 	LsmSvgLengthAttribute	cx;
 	LsmSvgLengthAttribute	cy;
 	LsmSvgLengthAttribute	r;
 	LsmSvgLengthAttribute	fx;
 	LsmSvgLengthAttribute	fy;
+	LsmSvgTransformAttribute transform;
+	LsmSvgPatternUnitsAttribute units;
+	LsmSvgSpreadMethodAtttribute spread_method;
+	LsmAttribute href;
+
+	gboolean enable_rendering;
 };
 
 struct _LsmSvgRadialGradientElementClass {
-	LsmSvgGradientElementClass  parent_class;
+	LsmSvgElementClass  parent_class;
 };
 
 GType lsm_svg_radial_gradient_element_get_type (void);
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 63b8f98..c4bdb13 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -25,7 +25,8 @@
 #include <lsmsvgdocument.h>
 #include <lsmsvgelement.h>
 #include <lsmsvgsvgelement.h>
-#include <lsmsvggradientelement.h>
+#include <lsmsvgradialgradientelement.h>
+#include <lsmsvglineargradientelement.h>
 #include <lsmsvgpatternelement.h>
 #include <lsmsvgmarkerelement.h>
 #include <lsmsvgclippathelement.h>
@@ -742,7 +743,8 @@ _paint_url (LsmSvgView *view,
 	LsmBox extents;
 
 	element = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document), url);
-	if (!LSM_IS_SVG_GRADIENT_ELEMENT (element) &&
+	if (!LSM_IS_SVG_RADIAL_GRADIENT_ELEMENT (element) &&
+	    !LSM_IS_SVG_LINEAR_GRADIENT_ELEMENT (element) &&
 	    !LSM_IS_SVG_PATTERN_ELEMENT (element))
 		return;
 
@@ -782,7 +784,7 @@ _paint_url (LsmSvgView *view,
 		}
 #endif
 
-		if (LSM_IS_SVG_GRADIENT_ELEMENT (element) &&
+		if ((LSM_IS_SVG_RADIAL_GRADIENT_ELEMENT (element) || LSM_IS_SVG_LINEAR_GRADIENT_ELEMENT (element)) &&
 		    view->pattern_data->units == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX) {
 			cairo_matrix_t matrix;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]