[lasem] svg_gradient: support for href.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg_gradient: support for href.
- Date: Thu, 12 Aug 2010 22:40:36 +0000 (UTC)
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]