[lasem] svg: add a transformable class for object with 'transform' attribute.



commit aa4885af652628985030a826576fdcd8e389b04b
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sun Sep 23 21:15:43 2012 +0200

    svg: add a transformable class for object with 'transform' attribute.
    
    It fixes a crash when 'transform' attribute is set on gradient elements.
    It also reduce the memory use.

 src/Makefile.am                                    |    2 +
 src/lsmsvgcircleelement.c                          |    2 +-
 src/lsmsvgcircleelement.h                          |    6 +-
 src/lsmsvgclippathelement.c                        |    2 +-
 src/lsmsvgclippathelement.h                        |    6 +-
 src/lsmsvgdefselement.c                            |    2 +-
 src/lsmsvgdefselement.h                            |    8 +-
 src/lsmsvgelement.c                                |   83 +++---
 src/lsmsvgelement.h                                |   17 +-
 src/lsmsvgellipseelement.c                         |    4 +-
 src/lsmsvgellipseelement.h                         |    8 +-
 src/lsmsvggelement.c                               |    2 +-
 src/lsmsvggelement.h                               |    6 +-
 src/lsmsvgimageelement.c                           |    4 +-
 src/lsmsvgimageelement.h                           |    8 +-
 src/lsmsvglineelement.c                            |    4 +-
 src/lsmsvglineelement.h                            |    8 +-
 src/lsmsvgpathelement.c                            |    2 +-
 src/lsmsvgpathelement.h                            |    6 +-
 src/lsmsvgpolygonelement.c                         |    4 +-
 src/lsmsvgpolygonelement.h                         |    8 +-
 src/lsmsvgpolylineelement.c                        |    4 +-
 src/lsmsvgpolylineelement.h                        |    8 +-
 src/lsmsvgrectelement.c                            |    4 +-
 src/lsmsvgrectelement.h                            |    8 +-
 src/lsmsvgtextelement.c                            |    4 +-
 src/lsmsvgtextelement.h                            |    8 +-
 src/lsmsvgtransformable.c                          |  107 ++++++++
 src/lsmsvgtransformable.h                          |   54 ++++
 src/lsmsvgtypes.h                                  |    1 +
 src/lsmsvguseelement.c                             |    9 +-
 src/lsmsvguseelement.h                             |    8 +-
 .../librsvg/librsvg-bug551736-mobile_phone_01.svg  |  276 ++++++++++++++++++++
 33 files changed, 558 insertions(+), 125 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7db910f..6535f24 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -100,6 +100,7 @@ LASEM_SVG_SRCS =				\
 	lsmsvgmatrix.c				\
 	lsmsvgdocument.c			\
 	lsmsvgelement.c				\
+	lsmsvgtransformable.c			\
 	lsmsvgclippathelement.c			\
 	lsmsvgsvgelement.c			\
 	lsmsvguseelement.c			\
@@ -204,6 +205,7 @@ LASEM_SVG_HDRS =				\
 	lsmsvgmatrix.h				\
 	lsmsvgdocument.h			\
 	lsmsvgelement.h				\
+	lsmsvgtransformable.h			\
 	lsmsvgclippathelement.h			\
 	lsmsvgsvgelement.h			\
 	lsmsvggelement.h			\
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index 00a8cbc..c8aedd4 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -144,4 +144,4 @@ lsm_svg_circle_element_class_init (LsmSvgCircleElementClass *s_rect_class)
 					      lsm_svg_circle_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgCircleElement, lsm_svg_circle_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgCircleElement, lsm_svg_circle_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgcircleelement.h b/src/lsmsvgcircleelement.h
index c45702d..4930428 100644
--- a/src/lsmsvgcircleelement.h
+++ b/src/lsmsvgcircleelement.h
@@ -25,7 +25,7 @@
 #define LSM_SVG_CIRCLE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgCircleElementClass LsmSvgCircleElementClass;
 
 struct _LsmSvgCircleElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	cx;
 	LsmSvgLengthAttribute	cy;
@@ -47,7 +47,7 @@ struct _LsmSvgCircleElement {
 };
 
 struct _LsmSvgCircleElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_circle_element_get_type (void);
diff --git a/src/lsmsvgclippathelement.c b/src/lsmsvgclippathelement.c
index 89b3109..2fe7386 100644
--- a/src/lsmsvgclippathelement.c
+++ b/src/lsmsvgclippathelement.c
@@ -130,4 +130,4 @@ lsm_svg_clip_path_element_class_init (LsmSvgClipPathElementClass *klass)
 					      lsm_svg_clip_path_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgClipPathElement, lsm_svg_clip_path_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgClipPathElement, lsm_svg_clip_path_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgclippathelement.h b/src/lsmsvgclippathelement.h
index 3873aa3..6bc9027 100644
--- a/src/lsmsvgclippathelement.h
+++ b/src/lsmsvgclippathelement.h
@@ -25,7 +25,7 @@
 #define LSM_SVG_CLIP_PATH_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgClipPathElementClass LsmSvgClipPathElementClass;
 
 struct _LsmSvgClipPathElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgPatternUnitsAttribute units;
 
@@ -47,7 +47,7 @@ struct _LsmSvgClipPathElement {
 };
 
 struct _LsmSvgClipPathElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_clip_path_element_get_type (void);
diff --git a/src/lsmsvgdefselement.c b/src/lsmsvgdefselement.c
index 43cf47c..accfee7 100644
--- a/src/lsmsvgdefselement.c
+++ b/src/lsmsvgdefselement.c
@@ -71,4 +71,4 @@ lsm_svg_defs_element_class_init (LsmSvgDefsElementClass *s_g_class)
 	s_element_class->render = NULL;
 }
 
-G_DEFINE_TYPE (LsmSvgDefsElement, lsm_svg_defs_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgDefsElement, lsm_svg_defs_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgdefselement.h b/src/lsmsvgdefselement.h
index 194f821..24322e9 100644
--- a/src/lsmsvgdefselement.h
+++ b/src/lsmsvgdefselement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_DEFS_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,11 +39,11 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgDefsElementClass LsmSvgDefsElementClass;
 
 struct _LsmSvgDefsElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 };
 
 struct _LsmSvgDefsElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_defs_element_get_type (void);
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 1746fbb..9ea52b4 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -26,6 +26,7 @@
 #include <lsmproperties.h>
 #include <lsmdomdocument.h>
 #include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 #include <lsmsvgpatternelement.h>
 #include <lsmsvgradialgradientelement.h>
 #include <lsmsvglineargradientelement.h>
@@ -158,8 +159,6 @@ lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
 	LsmSvgElementClass *element_class;
 	const LsmSvgStyle *parent_style;
 	LsmSvgStyle *style;
-	gboolean is_identity_transform;
-	gboolean is_matrix_invertible = TRUE;
 
 	g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
 
@@ -167,35 +166,27 @@ lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
 	if (element_class->render == NULL)
 		return;
 
-	is_identity_transform = lsm_svg_matrix_is_identity (&element->transform.matrix);
-
 	parent_style = lsm_svg_view_get_current_style (view);
 	style = lsm_svg_style_new_inherited (parent_style, &element->property_bag);
 
-	if (!is_identity_transform)
-		is_matrix_invertible = lsm_svg_view_push_matrix (view, &element->transform.matrix);
+	if (style->visibility->value == LSM_SVG_VISIBILITY_VISIBLE &&
+	    style->display->value != LSM_SVG_DISPLAY_NONE) {
 
-	if (is_identity_transform || is_matrix_invertible) {
+		lsm_debug_render ("[LsmSvgElement::render] Render %s (%s)",
+				  lsm_dom_node_get_node_name (LSM_DOM_NODE (element)),
+				  element->id.value != NULL ? element->id.value : "no id");
 		lsm_svg_view_push_element (view, element);
 		lsm_svg_view_push_style (view, style);
 
-
-		if (style->visibility->value == LSM_SVG_VISIBILITY_VISIBLE &&
-		    style->display->value != LSM_SVG_DISPLAY_NONE) {
-			lsm_debug_render ("[LsmSvgElement::render] Render %s (%s)",
-					  lsm_dom_node_get_node_name (LSM_DOM_NODE (element)),
-					  element->id.value != NULL ? element->id.value : "no id");
-
+		if (element_class->transformed_render)
+			element_class->transformed_render (element, view);
+		else
 			element_class->render (element, view);
-		}
 
 		lsm_svg_view_pop_style (view);
 		lsm_svg_view_pop_element (view);
 	}
 
-	if (!is_identity_transform)
-		lsm_svg_view_pop_matrix (view);
-
 	lsm_svg_style_unref (style);
 }
 
@@ -227,6 +218,22 @@ lsm_svg_element_force_render (LsmSvgElement *element, LsmSvgView *view)
 	lsm_svg_element_render (element, view);
 }
 
+void
+lsm_svg_element_transformed_get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents)
+{
+	LsmSvgElementClass *element_class;
+	g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (extents != NULL);
+
+	element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
+
+	if (element_class->transformed_get_extents != NULL)
+		element_class->transformed_get_extents (element, view, extents);
+	else
+		element_class->get_extents (element, view, extents);
+}
+
 static void
 _get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents)
 {
@@ -240,15 +247,15 @@ _get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents)
 		if (LSM_IS_SVG_ELEMENT (node)) {
 			LsmExtents child_extents;
 			LsmSvgElement *child_element;
+			LsmSvgElementClass *child_element_class;
 
 			child_element = LSM_SVG_ELEMENT (node);
-
-			lsm_svg_element_get_extents (child_element, view, &child_extents);
-
-			if (!lsm_svg_matrix_is_identity (&child_element->transform.matrix))
-				lsm_svg_matrix_transform_bounding_box (&child_element->transform.matrix,
-								       &extents->x1, &extents->y1,
-								       &extents->x2, &extents->y2);
+			child_element_class = LSM_SVG_ELEMENT_GET_CLASS (node);
+			
+			if (child_element_class->transformed_get_extents != NULL)
+				child_element_class->transformed_get_extents (child_element, view, &child_extents);
+			else
+				child_element_class->get_extents (child_element, view, &child_extents);
 
 			if (first_child) {
 				element_extents = child_extents;
@@ -275,29 +282,21 @@ lsm_svg_element_get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtent
 	g_return_if_fail (extents != NULL);
 
 	element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
-	if (element_class->get_extents != NULL) {
-		element_class->get_extents (element, view, extents);
+	element_class->get_extents (element, view, extents);
 
-		if (element->id.value != NULL)
-			lsm_debug_measure ("LsmSvgElement::get_extents] Extents for '%s' = %g,%g %g,%g",
+	if (element->id.value != NULL)
+		lsm_debug_measure ("LsmSvgElement::get_extents] Extents for '%s' = %g,%g %g,%g",
 				   element->id.value,
 				   extents->x1, extents->y1, extents->x2, extents->y2);
-		else
-			lsm_debug_measure ("LsmSvgElement::get_extents] Extents for <%s> = %g,%g %g,%g",
+	else
+		lsm_debug_measure ("LsmSvgElement::get_extents] Extents for <%s> = %g,%g %g,%g",
 				   lsm_dom_node_get_node_name (LSM_DOM_NODE (element)),
 				   extents->x1, extents->y1, extents->x2, extents->y2);
-	} else {
-		extents->x1 = 0.0;
-		extents->y1 = 0.0;
-		extents->x2 = 0.0;
-		extents->y2 = 0.0;
-	}
 }
 
 static void
 lsm_svg_element_init (LsmSvgElement *element)
 {
-	lsm_svg_matrix_init_identity (&element->transform.matrix);
 }
 
 static void
@@ -331,12 +330,6 @@ static const LsmAttributeInfos lsm_svg_attribute_infos[] = {
 		.name = "class",
 		.trait_class = &lsm_null_trait_class,
 		.attribute_offset = offsetof (LsmSvgElement, class_name)
-	},
-	{
-		.name = "transform",
-		.attribute_offset = offsetof (LsmSvgElement, transform),
-		.trait_class = &lsm_svg_matrix_trait_class,
-		.trait_default = &matrix_default
 	}
 };
 
@@ -362,6 +355,8 @@ lsm_svg_element_class_init (LsmSvgElementClass *s_element_class)
 
 	s_element_class->render = _render;
 	s_element_class->get_extents = _get_extents;
+	s_element_class->transformed_render = NULL;
+	s_element_class->transformed_get_extents = NULL;
 	s_element_class->attribute_manager = lsm_attribute_manager_new (G_N_ELEMENTS (lsm_svg_attribute_infos),
 									lsm_svg_attribute_infos);
 }
diff --git a/src/lsmsvgelement.h b/src/lsmsvgelement.h
index 380d75f..6adf00a 100644
--- a/src/lsmsvgelement.h
+++ b/src/lsmsvgelement.h
@@ -48,7 +48,6 @@ struct _LsmSvgElement {
 
 	LsmAttribute			id;
 	LsmAttribute			class_name;
-	LsmSvgTransformAttribute 	transform;
 };
 
 struct _LsmSvgElementClass {
@@ -58,18 +57,22 @@ struct _LsmSvgElementClass {
 
 	LsmSvgElementCategory category;
 
-	void		(*enable_rendering)	(LsmSvgElement *element);
-	void 		(*render)		(LsmSvgElement *element, LsmSvgView *view);
-	void 		(*get_extents)		(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
+	void		(*enable_rendering)		(LsmSvgElement *element);
+	void 		(*render)			(LsmSvgElement *element, LsmSvgView *view);
+	void 		(*get_extents)			(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
+	void 		(*transformed_render)		(LsmSvgElement *element, LsmSvgView *view);
+	void 		(*transformed_get_extents)	(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
 };
 
 GType lsm_svg_element_get_type (void);
 
 LsmSvgElementCategory	lsm_svg_element_get_category	(LsmSvgElement *element);
 
-void 		lsm_svg_element_render 		(LsmSvgElement *element, LsmSvgView *view);
-void 		lsm_svg_element_force_render 	(LsmSvgElement *element, LsmSvgView *view);
-void		lsm_svg_element_get_extents	(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
+void 		lsm_svg_element_render 				(LsmSvgElement *element, LsmSvgView *view);
+void 		lsm_svg_element_render 				(LsmSvgElement *element, LsmSvgView *view);
+void 		lsm_svg_element_force_render 			(LsmSvgElement *element, LsmSvgView *view);
+void		lsm_svg_element_get_extents			(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
+void 		lsm_svg_element_transformed_get_extents 	(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
 
 G_END_DECLS
 
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index 822d277..77280fe 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -132,4 +132,4 @@ lsm_svg_ellipse_element_class_init (LsmSvgEllipseElementClass *s_rect_class)
 					      lsm_svg_ellipse_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgEllipseElement, lsm_svg_ellipse_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgEllipseElement, lsm_svg_ellipse_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgellipseelement.h b/src/lsmsvgellipseelement.h
index 039e789..249b31c 100644
--- a/src/lsmsvgellipseelement.h
+++ b/src/lsmsvgellipseelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_ELLIPSE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgEllipseElementClass LsmSvgEllipseElementClass;
 
 struct _LsmSvgEllipseElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	cx;
 	LsmSvgLengthAttribute	cy;
@@ -48,7 +48,7 @@ struct _LsmSvgEllipseElement {
 };
 
 struct _LsmSvgEllipseElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_ellipse_element_get_type (void);
diff --git a/src/lsmsvggelement.c b/src/lsmsvggelement.c
index 8c4f1c3..96d8dea 100644
--- a/src/lsmsvggelement.c
+++ b/src/lsmsvggelement.c
@@ -70,4 +70,4 @@ lsm_svg_g_element_class_init (LsmSvgGElementClass *s_g_class)
 		LSM_SVG_ELEMENT_CATEGORY_STRUCTURAL;
 }
 
-G_DEFINE_TYPE (LsmSvgGElement, lsm_svg_g_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgGElement, lsm_svg_g_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvggelement.h b/src/lsmsvggelement.h
index 378761e..fabebab 100644
--- a/src/lsmsvggelement.h
+++ b/src/lsmsvggelement.h
@@ -25,7 +25,7 @@
 #define LSM_SVG_G_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,11 +39,11 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgGElementClass LsmSvgGElementClass;
 
 struct _LsmSvgGElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 };
 
 struct _LsmSvgGElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_g_element_get_type (void);
diff --git a/src/lsmsvgimageelement.c b/src/lsmsvgimageelement.c
index 58f1d45..6fe0653 100644
--- a/src/lsmsvgimageelement.c
+++ b/src/lsmsvgimageelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -250,4 +250,4 @@ lsm_svg_image_element_class_init (LsmSvgImageElementClass *klass)
 					      lsm_svg_image_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgImageElement, lsm_svg_image_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgImageElement, lsm_svg_image_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgimageelement.h b/src/lsmsvgimageelement.h
index 232b2cc..c89c944 100644
--- a/src/lsmsvgimageelement.h
+++ b/src/lsmsvgimageelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_IMAGE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 G_BEGIN_DECLS
@@ -40,7 +40,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgImageElementClass LsmSvgImageElementClass;
 
 struct _LsmSvgImageElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	x;
 	LsmSvgLengthAttribute	y;
@@ -55,7 +55,7 @@ struct _LsmSvgImageElement {
 };
 
 struct _LsmSvgImageElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_image_element_get_type (void);
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index ba8c0b8..2d2e98a 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -126,4 +126,4 @@ lsm_svg_line_element_class_init (LsmSvgLineElementClass *s_rect_class)
 					      lsm_svg_line_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgLineElement, lsm_svg_line_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgLineElement, lsm_svg_line_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvglineelement.h b/src/lsmsvglineelement.h
index 2dab4cf..5630612 100644
--- a/src/lsmsvglineelement.h
+++ b/src/lsmsvglineelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_LINE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgLineElementClass LsmSvgLineElementClass;
 
 struct _LsmSvgLineElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	x1;
 	LsmSvgLengthAttribute	y1;
@@ -48,7 +48,7 @@ struct _LsmSvgLineElement {
 };
 
 struct _LsmSvgLineElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_line_element_get_type (void);
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index 73f52e8..3715319 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -112,4 +112,4 @@ lsm_svg_path_element_class_init (LsmSvgPathElementClass *s_rect_class)
 					      lsm_svg_path_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgPathElement, lsm_svg_path_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgPathElement, lsm_svg_path_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgpathelement.h b/src/lsmsvgpathelement.h
index e4881e5..de7817c 100644
--- a/src/lsmsvgpathelement.h
+++ b/src/lsmsvgpathelement.h
@@ -25,7 +25,7 @@
 #define LSM_SVG_PATH_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,14 +39,14 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgPathElementClass LsmSvgPathElementClass;
 
 struct _LsmSvgPathElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmAttribute 		d;
 	LsmSvgDoubleAttribute 	path_length;
 };
 
 struct _LsmSvgPathElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_path_element_get_type (void);
diff --git a/src/lsmsvgpolygonelement.c b/src/lsmsvgpolygonelement.c
index 110fe46..9e17733 100644
--- a/src/lsmsvgpolygonelement.c
+++ b/src/lsmsvgpolygonelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -92,4 +92,4 @@ lsm_svg_polygon_element_class_init (LsmSvgPolygonElementClass *s_rect_class)
 					      lsm_svg_polygon_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgPolygonElement, lsm_svg_polygon_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgPolygonElement, lsm_svg_polygon_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgpolygonelement.h b/src/lsmsvgpolygonelement.h
index 02b49fa..680c4d7 100644
--- a/src/lsmsvgpolygonelement.h
+++ b/src/lsmsvgpolygonelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_POLYGON_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,13 +39,13 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgPolygonElementClass LsmSvgPolygonElementClass;
 
 struct _LsmSvgPolygonElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmAttribute	points;
 };
 
 struct _LsmSvgPolygonElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass  base_class;
 };
 
 GType lsm_svg_polygon_element_get_type (void);
diff --git a/src/lsmsvgpolylineelement.c b/src/lsmsvgpolylineelement.c
index a20a19b..49bae43 100644
--- a/src/lsmsvgpolylineelement.c
+++ b/src/lsmsvgpolylineelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -92,4 +92,4 @@ lsm_svg_polyline_element_class_init (LsmSvgPolylineElementClass *s_rect_class)
 					      lsm_svg_polyline_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgPolylineElement, lsm_svg_polyline_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgPolylineElement, lsm_svg_polyline_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgpolylineelement.h b/src/lsmsvgpolylineelement.h
index 49e9a1a..9165267 100644
--- a/src/lsmsvgpolylineelement.h
+++ b/src/lsmsvgpolylineelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_POLYLINE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,13 +39,13 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgPolylineElementClass LsmSvgPolylineElementClass;
 
 struct _LsmSvgPolylineElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmAttribute	points;
 };
 
 struct _LsmSvgPolylineElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass base_class;
 };
 
 GType lsm_svg_polyline_element_get_type (void);
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index 617f49e..36be4bf 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -179,4 +179,4 @@ lsm_svg_rect_element_class_init (LsmSvgRectElementClass *s_rect_class)
 					      lsm_svg_rect_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgRectElement, lsm_svg_rect_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgRectElement, lsm_svg_rect_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgrectelement.h b/src/lsmsvgrectelement.h
index 7e652c5..95f1e15 100644
--- a/src/lsmsvgrectelement.h
+++ b/src/lsmsvgrectelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_RECT_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgRectElementClass LsmSvgRectElementClass;
 
 struct _LsmSvgRectElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	x;
 	LsmSvgLengthAttribute	y;
@@ -50,7 +50,7 @@ struct _LsmSvgRectElement {
 };
 
 struct _LsmSvgRectElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass base_class;
 };
 
 GType lsm_svg_rect_element_get_type (void);
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index f41eff2..cf9bf4e 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -142,4 +142,4 @@ lsm_svg_text_element_class_init (LsmSvgTextElementClass *s_text_class)
 					      lsm_svg_text_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgTextElement, lsm_svg_text_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgTextElement, lsm_svg_text_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvgtextelement.h b/src/lsmsvgtextelement.h
index 56d0412..4cd8421 100644
--- a/src/lsmsvgtextelement.h
+++ b/src/lsmsvgtextelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_TEXT_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -39,14 +39,14 @@ G_BEGIN_DECLS
 typedef struct _LsmSvgTextElementClass LsmSvgTextElementClass;
 
 struct _LsmSvgTextElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	x;
 	LsmSvgLengthAttribute	y;
 };
 
 struct _LsmSvgTextElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass base_class;
 };
 
 GType lsm_svg_text_element_get_type (void);
diff --git a/src/lsmsvgtransformable.c b/src/lsmsvgtransformable.c
new file mode 100644
index 0000000..989bc47
--- /dev/null
+++ b/src/lsmsvgtransformable.c
@@ -0,0 +1,107 @@
+/* Lasem
+ *
+ * Copyright  2009 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * 	Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmdebug.h>
+#include <lsmsvgtransformable.h>
+#include <lsmsvgview.h>
+
+static GObjectClass *parent_class;
+
+/* LsmDomNode implementation */
+
+/* LsmDomElement implementation */
+
+/* LsmSvgTransformable implementation */
+
+static void
+lsm_svg_transformable_transformed_render (LsmSvgElement *element, LsmSvgView *view)
+{
+	LsmSvgTransformable *transformable = LSM_SVG_TRANSFORMABLE (element);
+	LsmSvgElementClass *element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
+	gboolean is_identity_transform;
+	gboolean is_matrix_invertible = TRUE;
+
+	is_identity_transform = lsm_svg_matrix_is_identity (&transformable->transform.matrix);
+
+	if (!is_identity_transform)
+		is_matrix_invertible = lsm_svg_view_push_matrix (view, &transformable->transform.matrix);
+	else
+		is_matrix_invertible = TRUE;
+
+	if (is_matrix_invertible)
+		element_class->render (element, view);
+
+	if (!is_identity_transform)
+		lsm_svg_view_pop_matrix (view);
+}
+
+static void
+lsm_svg_transformable_transformed_get_extents (LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents)
+{
+	LsmSvgTransformable *transformable = LSM_SVG_TRANSFORMABLE (element);
+	LsmSvgElementClass *element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
+
+	element_class->get_extents (element, view, extents);
+
+	if (!lsm_svg_matrix_is_identity (&transformable->transform.matrix))
+		lsm_svg_matrix_transform_bounding_box (&transformable->transform.matrix,
+						       &extents->x1, &extents->y1,
+						       &extents->x2, &extents->y2);
+}
+
+static void
+lsm_svg_transformable_init (LsmSvgTransformable *transformable)
+{
+	lsm_svg_matrix_init_identity (&transformable->transform.matrix);
+}
+
+/* LsmSvgTransformable class */
+
+static const LsmSvgMatrix matrix_default =	 { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, LSM_SVG_MATRIX_FLAGS_IDENTITY};
+
+static const LsmAttributeInfos lsm_svg_transformable_attribute_infos[] = {
+	{
+		.name = "transform",
+		.attribute_offset = offsetof (LsmSvgTransformable, transform),
+		.trait_class = &lsm_svg_matrix_trait_class,
+		.trait_default = &matrix_default
+	}
+};
+
+static void
+lsm_svg_transformable_class_init (LsmSvgTransformableClass *klass)
+{
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	s_element_class->transformed_render = lsm_svg_transformable_transformed_render;
+	s_element_class->transformed_get_extents = lsm_svg_transformable_transformed_get_extents;
+	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_transformable_attribute_infos),
+					      lsm_svg_transformable_attribute_infos);
+}
+
+G_DEFINE_ABSTRACT_TYPE (LsmSvgTransformable, lsm_svg_transformable, LSM_TYPE_SVG_ELEMENT)
diff --git a/src/lsmsvgtransformable.h b/src/lsmsvgtransformable.h
new file mode 100644
index 0000000..16bf60b
--- /dev/null
+++ b/src/lsmsvgtransformable.h
@@ -0,0 +1,54 @@
+/* Lasem
+ *
+ * Copyright  2007-2012 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * 	Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_SVG_TRANSFORMABLE_H
+#define LSM_SVG_TRANSFORMABLE_H
+
+#include <lsmsvgelement.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_TRANSFORMABLE             (lsm_svg_transformable_get_type ())
+#define LSM_SVG_TRANSFORMABLE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_TRANSFORMABLE, LsmSvgTransformable))
+#define LSM_SVG_TRANSFORMABLE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_TRANSFORMABLE, LsmSvgTransformableClass))
+#define LSM_IS_SVG_TRANSFORMABLE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_TRANSFORMABLE))
+#define LSM_IS_SVG_TRANSFORMABLE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_TRANSFORMABLE))
+#define LSM_SVG_TRANSFORMABLE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_TRANSFORMABLE, LsmSvgTransformableClass))
+
+typedef struct _LsmSvgTransformableClass LsmSvgTransformableClass;
+
+struct _LsmSvgTransformable {
+	LsmSvgElement	element;
+
+	LsmSvgTransformAttribute 	transform;
+};
+
+struct _LsmSvgTransformableClass {
+	LsmSvgElementClass  parent_class;
+};
+
+GType 	lsm_svg_transformable_get_type 			(void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgtypes.h b/src/lsmsvgtypes.h
index 7cb5b30..8ef45d8 100644
--- a/src/lsmsvgtypes.h
+++ b/src/lsmsvgtypes.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
 
 typedef struct _LsmSvgDocument LsmSvgDocument;
 typedef struct _LsmSvgElement LsmSvgElement;
+typedef struct _LsmSvgTransformable LsmSvgTransformable;
 typedef struct _LsmSvgGraphic LsmSvgGraphic;
 typedef struct _LsmSvgClipPathElement LsmSvgClipPathElement;
 typedef struct _LsmSvgSvgElement LsmSvgSvgElement;
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index 4298719..1ed8f69 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -143,12 +143,7 @@ lsm_svg_use_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExten
 	y = lsm_svg_view_normalize_length (view, &use_element->y.length,
 					   LSM_SVG_LENGTH_DIRECTION_VERTICAL);
 
-	lsm_svg_element_get_extents (LSM_SVG_ELEMENT (element), view, extents);
-
-	if (!lsm_svg_matrix_is_identity (&LSM_SVG_ELEMENT (element)->transform.matrix))
-		lsm_svg_matrix_transform_bounding_box (&LSM_SVG_ELEMENT (element)->transform.matrix,
-						       &extents->x1, &extents->y1,
-						       &extents->x2, &extents->y2);
+	lsm_svg_element_transformed_get_extents (LSM_SVG_ELEMENT (element), view, extents);
 
 	lsm_svg_matrix_init_translate (&matrix, x, y);
 
@@ -239,4 +234,4 @@ lsm_svg_use_element_class_init (LsmSvgUseElementClass *klass)
 					      lsm_svg_use_element_attribute_infos);
 }
 
-G_DEFINE_TYPE (LsmSvgUseElement, lsm_svg_use_element, LSM_TYPE_SVG_ELEMENT)
+G_DEFINE_TYPE (LsmSvgUseElement, lsm_svg_use_element, LSM_TYPE_SVG_TRANSFORMABLE)
diff --git a/src/lsmsvguseelement.h b/src/lsmsvguseelement.h
index e70174f..aef8a81 100644
--- a/src/lsmsvguseelement.h
+++ b/src/lsmsvguseelement.h
@@ -1,6 +1,6 @@
 /* Lasem
  *
- * Copyright  2009 Emmanuel Pacaud
+ * Copyright  2009-2012 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,7 @@
 #define LSM_SVG_USE_ELEMENT_H
 
 #include <lsmsvgtypes.h>
-#include <lsmsvgelement.h>
+#include <lsmsvgtransformable.h>
 
 G_BEGIN_DECLS
 
@@ -44,7 +44,7 @@ typedef enum {
 typedef struct _LsmSvgUseElementClass LsmSvgUseElementClass;
 
 struct _LsmSvgUseElement {
-	LsmSvgElement element;
+	LsmSvgTransformable base;
 
 	LsmSvgLengthAttribute	x;
 	LsmSvgLengthAttribute	y;
@@ -57,7 +57,7 @@ struct _LsmSvgUseElement {
 };
 
 struct _LsmSvgUseElementClass {
-	LsmSvgElementClass  element_class;
+	LsmSvgTransformableClass base_class;
 };
 
 GType lsm_svg_use_element_get_type (void);
diff --git a/tests/data/svg/librsvg/librsvg-bug551736-mobile_phone_01.svg b/tests/data/svg/librsvg/librsvg-bug551736-mobile_phone_01.svg
new file mode 100644
index 0000000..6f9a72f
--- /dev/null
+++ b/tests/data/svg/librsvg/librsvg-bug551736-mobile_phone_01.svg
@@ -0,0 +1,276 @@
+<?xml version="1.0"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd";>
+<!--check out www.treebuilder.de-->
+<svg xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink"; style="fill-rule:evenodd" viewBox="0 0 2480 3508">
+
+	 <defs>
+		<linearGradient id="metall" transform="rotate(90)">
+			<stop offset="17,4 %" stop-color="grey"/>
+			<stop offset="38,7 %" stop-color="black"/>
+			<stop offset="57,7 %" stop-color="lightgrey"/>
+			<stop offset="100 %" stop-color="black"/>
+		</linearGradient>
+		<radialGradient id="metall2"  fx="30%" fy="45%" >
+			<stop offset="0%" stop-color="#ffffff"/>
+			<stop offset="100%" stop-color="black"/> 
+		</radialGradient>
+
+		<path id="hg" filter="url(#Zebra)" fill="url(#metall)" d="M693 379c210,-135 1118,-134 1172,55 42,145 39,567 19,878 -33,523 -131,1699 -150,1744 -32,73 -875,82 -942,-12 -66,-95 -308, -2530 -99,-2665zm711 2619c17,-25 45,-56 89,-77 43,-21 134,-38 131, -27 -34,104 -242,215 -248,183 -3,-18 10,-52 28,-79zm-257 -4c-17,-26 -45,-57 -89,-78 -43,-21 -135,-37 -131,-26 36,96 243,210 248,183 3,-19 -10,-52 -28,-79zm-248 -849c20,7 139,38 138,25 -9,-87 -342,-334 -335, -270 6,64 21,128 31,180 4,18 135,53 166,65zm24 280c18,7 126,31 123,19 -24,-102 -296,-289 -288,-235 8,54 23,112 32,156 4,17 105,49 133,60zm10 232c18,7 152,41 151,29 -8,-77 -282,-258 -272,-201 10,56 33,98 44,139 4, 16 49,22 77,33zm498 169c41,1 -77,118 -153,112 -77,-5 -175,-100 -147, -114 1,0 296,2 300,2zm10 -216c46,1 -87,133 -173,127 -86,-6 -198,-114 -166,-129 1,0 334,2 339,2zm-2 -238c48,1 -91,138 -180,132 -90,-6 -206, -118 -173,-134 1,-1 348,1 353,2zm176 -235c-20,8 -139,39 -138,26 8,-88 331,-332 324,-268 -7,65 -10,126 -21,178 -
 3,18 -134,53 -165,64zm-169 -32c51,1 -98,149 -194,142 -96,-6 -221,-127 -186,-143 2,-1 375,1 380,1zm162 291c-18,6 -125,30 -122,18 23,-101 288,-285 280,-232 -9,54 -15,109 -24,154 -4,16 -105,49 -134,60zm13 239c-18,7 -153,41 -151,29 8,-77 265,-255 255,-199 -10,57 -16,96 -27,137 -5,16 -49,22 -77,33z"/>
+		<path id="hg_unten" fill="url(#metall2)" d="M1863 1630c-52,759 -109,1404 -128,1448 -32,74 -880,83 -947,-12 -38,-54 -121,-765 -157,-1481 12,182 79,958 264,1283 185,325 584,324 747,22 152,-283 200,-1018 221,-1260z"/>
+		<path id="hg_oben" fill="url(#metall)" d="M712 455c28,-148 1055,-137 1098,16 43,153 -51,1048 -181,1323 -129,274 -594,280 -760,-25 -166,-304 -184,-1167 -157,-1314zm377 162c22,-20 107,21 166,23 58,1 149,-42 170,-25 20,18 -73,69 -167,67 -86,-2 -192,-45 -169,-65zm113 -32c7,-6 40,-1 58,-1 17,1 42,-5 49,1 6,5 -21,34 -50,33 -26,0 -63,-27 -57,-33zm-430 310c315,-29 665,-23 974,4 -21,197 -77,553 -112,615 -17,33 -202,85 -391,86 -174,1 -346,-41 -378,-81 -55,-72 -84,-447 -93,-624z"/>
+		<path id="display" d="M772 895c315,-29 665,-23 974,4 -21,197 -77,553 -112,615 -17,33 -202,85 -391,86 -174,1 -346,-41 -378,-81 -55,-72 -84,-447 -93,-624z"/>
+		<path id="linien" fill="url(#metall2)" d="M874 1790c-3,-3 -5,-7 -8,-12 -165,-304 -171,-1236 -156,-1314 14,-78 6,-16 14,-23 -15,259 21,986 171,1271 22,42 68,90 98,118 -5,-3 -10,-5 -15,-7 -53,-21 -108,-53 -107,-42 0,3 1,5 3,9zm661 42c31,-16 92,-51 97,-46 126,-290 218,-1155 175,-1305 -1,-6 -4,-11 -8,-16 17,256 -75,1013 -206,1278 -16,34 -36,64 -58,89z"/>
+	
+		<g id="knopf_oben" fill="url(#metall2)">
+			<path d="M1302 1831c-3,-9 67,-23 67,-36 -2,-27 -66,-153 -115,-152 -50,2 -119,127 -118,152 0,13 70,22 68,34 -2,12 -82,12 -81,30 1,25 63,136 133,137 70,2 126,-110 133,-137 4,-16 -84,-19 -87,-28z"/>
+			<path d="M1046 1618c-19,-3 -120,-15 -123,15 -3,40 91,142 113,141 22,-1 115,-100 106,-126 -3,-10 -67,-26 -96,-30z"/>
+			<path d="M1465 1622c19,-2 120,-14 123,15 3,40 -91,143 -113,142 -22,-2 -115,-100 -106,-127 3,-9 67,-26 96,-30z"/>
+			<path d="M1067 1892c-16,-21 -54,-61 -88,-74 -54,-19 -110,-49 -109,-38 5,39 114,133 149,149 35,16 103,54 95,38 -14,-27 -30,-53 -47,-75z"/>
+			<path d="M1585 1865c-15,21 -62,68 -96,81 -53,21 -100,45 -99,33 4,-39 112,-134 146,-150 35,-17 103,-56 95,-40 -14,27 -29,53 -46,76z"/>
+		</g>
+		<g id="knopf_unten" fill="url(#metall2)">
+			<path d="M1620 2637c-18,7 -153,42 -151,30 8,-77 265,-256 255,-199 -10,56 -16,95 -27,137 -5,16 -49,22 -77,32z"/>
+			<path d="M1607 2398c-18,7 -125,31 -122,19 23,-102 288,-286 280,-232 -9,53 -15,109 -25,153 -3,17 -104,49 -133,60z"/>
+			<path d="M1444 2107c52,2 -97,149 -193,143 -96,-7 -221,-127 -186,-144 2,-1 375,1 379,1z"/>
+			<path d="M1613 2140c-19,7 -139,38 -137,25 8,-87 331,-332 324,-267 -7,64 -10,125 -21,177 -3,18 -135,53 -166,65z"/>
+			<path d="M1438 2374c48,1 -91,138 -180,132 -90,-6 -206,-118 -174,-134 2,0 349,2 354,2z"/>
+			<path d="M1440 2612c46,1 -87,133 -173,127 -86,-6 -198,-113 -166,-129 1,0 334,2 339,2z"/>
+			<path d="M1430 2828c41,1 -77,118 -153,113 -77,-6 -175,-101 -148,-114 1,-1 297,1 301,1z"/>
+			<path d="M932 2659c18,7 152,42 151,30 -9,-77 -282,-259 -272,-202 10,57 33,98 44,140 4,16 48,22 77,32z"/>
+			<path d="M922 2427c18,7 125,31 123,19 -24,-102 -296,-288 -288,-235 8,54 23,112 32,157 4,16 104,48 133,59z"/>
+			<path d="M898 2147c19,7 139,38 138,25 -9,-87 -343,-334 -336,-270 7,65 22,128 32,181 4,17 135,52 166,64z"/>
+			<path d="M1146 2996c-18,-25 -45,-56 -89,-78 -43,-21 -135,-37 -131,-26 36,96 243,210 248,183 3,-18 -10,-52 -28,-79z"/>
+			<path d="M1403 3001c17,-26 45,-57 89,-78 43,-21 134,-37 131,-26 -34,103 -243,214 -248,182 -3,-18 10,-52 28,-78z"/>
+		</g> 
+		 <g id="knopf_text_oben" fill="black">
+			<path d="M960 1653c22,1 44,2 65,4 19,2 46,10 64,13 39,7 -80,-8 -119,-3 -3,-5 -18,-15 -10,-14z"/>
+			<path d="M1545 1653c-22,1 -44,2 -66,4 -18,2 -45,10 -64,13 -39,7 80,-8 120,-3 3,-5 18,-15 10,-14z"/>
+			<path d="M1208 1746c26,-16 37,-21 46,-21 10,-1 21,8 47,22 -9,-16 -34,-54 -47,-53 -13,1 -44,42 -46,52z"/>
+			<path d="M1208 1905c26,16 37,21 46,21 10,1 21,-8 47,-22 -9,16 -34,54 -47,53 -13,-1 -44,-42 -46,-52z"/>
+			<path fill="limegreen" d="M936 1852c7,5 16,12 23,17 2,-3 5,-8 7,-9 3,-2 6,-3 11,0l21 15c7,6 18,11 22,16 5,5 3,11 3,13 -1,2 -1,1 -3,8 6,5 10,7 16,12 5,-9 11,-19 11,-24 -1,-5 -4,-11 -9,-14l-58 -40c-7,-4 -14,-10 -20,-11 -6,-2 -8,0 -12,3 -5,3 -8,9 -12,14z"/>
+			<path fill="red" d="M1482 1931c7,-5 16,-11 23,-16 -2,-3 -6,-7 -7,-10 -1,-3 -1,-6 4,-10l20 -15c8,-6 16,-14 22,-17 6,-3 11,0 13,1 2,2 1,1 7,6 7,-5 10,-8 16,-13 -7,-6 -14,-15 -19,-16 -5,-1 -12,0 -17,4l-55 43c-6,5 -14,10 -17,16 -3,5 -2,8 0,12 1,5 6,11 10,15z"/>
+			<path fill="red" d="M1526 1911l-4 -4c-1,-1 -1,-3 1,-5l17 -14c2,-1 4,-1 5,0l3 4c1,2 1,4 0,5l-18 14c-1,2 -3,1 -4,0z"/>
+		</g>
+		 <g id="knopf_text_unten" fill="black">
+			<path d="M788 2070l-13 -4 19 -58 -12 -4 3 -10 25 8 -22 68zm102 -7l-3 8c-4,2 -8,2 -11,2 -3,0 -6,0 -9,-1 -1,0 -3,-1 -4,-2 -1,0 -3,-1 -4,-2 -1,-1 -2,-2 -3,-3 -6,-4 -11,-7 -14,-8 -3,-1 -5,-1 -9,-1 -3,0 -7,1 -11,3l3 -9c4,-1 7,-2 11,-2 3,0 6,0 9,1 2,1 3,2 5,3 2,1 5,2 7,4 1,1 1,1 2,2 5,3 8,5 11,6 2,1 5,1 9,1 3,0 7,-1 11,-2z"/>
+			<path d="M842 2339l12 -27 -29 19 17 8zm2 26l-11 -5 5 -10 -29 -13 5 -10 47 -33 12 6 -19 44 5 2 -5 11 -5 -2 -5 10zm61 -18l5 2 -22 49 -4 -2 7 -17c-2,1 -5,2 -8,2 -3,0 -6,-1 -9,-2 -5,-2 -9,-6 -11,-12 -2,-5 -2,-10 1,-16 2,-5 6,-9 11,-11 6,-2 11,-2 17,0 3,2 5,3 7,6 1,2 3,4 3,7l3 -6zm-8 18c2,-3 2,-7 0,-12 -1,-4 -4,-7 -7,-8 -4,-2 -8,-2 -12,0 -4,1 -7,4 -9,9 -2,4 -2,8 -1,12 2,4 5,7 8,9 4,1 8,1 12,-1 4,-1 7,-4 9,-9zm25 -24l5 2 -7 16c2,-1 4,-2 6,-2 3,0 5,1 7,2 6,2 9,5 10,9 1,4 0,10 -3,16l-8 19 -5 -2 8 -19c3,-5 4,-9 3,-12 -1,-3 -3,-5 -7,-7 -2,-1 -4,-1 -6,-1 -2,0 -4,1 -6,2 -1,1 -1,2 -2,3 -1,1 -2,3 -4,7l-7 17 -5 -2 21 -48zm40 26l-5 -2 4 -7 5 2 -4 7zm-23 39l17 -37 4 3 -16 36 -5 -2z"/>
+			<path d="M875 2605l-13 -6 48 -43 -25 -11 5 -11 37 16 -5 12 -47 43zm50 -22l5 2 -3 6c2,-2 5,-2 8,-2 3,-1 6,0 9,1 5,3 9,6 11,12 2,5 2,11 0,16 -3,5 -7,9 -12,11 -5,2 -10,2 -16,0 -3,-1 -5,-3 -7,-5 -2,-3 -3,-5 -4,-8l-1 3 -2 5 -5 10 -4 -2 21 -49zm-3 20c-2,4 -2,9 -1,13 2,4 4,7 8,9 4,1 8,1 12,0 4,-2 7,-5 9,-9 1,-4 2,-8 0,-13 -1,-4 -4,-7 -8,-8 -4,-2 -8,-2 -12,0 -4,1 -6,4 -8,8zm78 13l4 2 -21 48 -5 -2 8 -17c-3,1 -5,2 -8,2 -3,0 -6,0 -9,-2 -5,-2 -9,-6 -11,-11 -2,-5 -2,-11 0,-16 3,-6 7,-10 12,-12 5,-2 11,-2 16,1 3,1 5,3 7,5 2,2 3,5 4,7l3 -5zm-8 18c1,-4 1,-8 0,-12 -2,-4 -4,-7 -8,-9 -4,-2 -8,-2 -12,0 -4,2 -7,5 -9,9 -2,4 -2,8 0,12 1,4 4,7 8,9 4,2 8,2 12,0 4,-2 7,-5 9,-9zm8 26l-4 -2 16 -37 4 2 -2 4c2,-1 4,-2 6,-2 1,0 3,0 5,1l-2 5c-3,-1 -6,-1 -8,0 -2,1 -3,3 -5,7l-10 22zm15 -7l5 2 0 0c-1,2 -1,4 0,7 0,2 2,3 4,4 2,1 3,1 5,0 2,0 3,-2 4,-3 1,-2 1,-4 0,-5 0,-2 -2,-4 -4,-6 -3,-3 -5,-5 -6,-8 0,-2 0,-4 1,-6 1,-3 3,-5 6,-6 3,-2 6,-1 9,0 3,1 6,3 7,6 1,2 1,5 -1,9l-5 -3c1,-1 1,-3 0,-4 0,-2 -1,-3 -3,-4 -2,
 0 -3,0 -5,0 -1,1 -2,2 -3,3 0,2 0,3 0,4 0,0 0,1 1,2 0,1 2,3 3,4 1,1 2,2 3,2 2,2 3,4 3,7 1,2 0,4 -1,7 -1,3 -3,5 -7,6 -3,1 -6,1 -9,-1 -4,-1 -6,-3 -7,-7 -1,-3 -1,-6 0,-10z"/>
+			<path d="M1614 2088c-2,-4 -4,-8 -8,-10 -4,-2 -8,-3 -12,-2 -4,2 -7,4 -9,8 -2,4 -2,8 -1,12 1,5 4,8 8,10 4,2 8,3 12,2 4,-2 6,-4 8,-8 3,-4 3,-8 2,-12zm-4 -14l-3 -8 -3 -10 5 -2 15 51 -5 2 -2 -6c-1,3 -2,5 -5,7 -2,2 -4,3 -7,4 -6,2 -11,1 -16,-1 -5,-3 -8,-8 -10,-13 -2,-6 -1,-11 1,-16 3,-5 7,-9 13,-10 3,-1 6,-1 9,-1 3,1 5,2 8,3zm55 0l-35 10c1,5 4,8 7,9 4,2 8,2 12,1 3,-1 5,-2 7,-4 2,-3 3,-5 3,-8l6 -2c0,5 -2,9 -5,12 -2,3 -5,6 -10,7 -5,2 -11,1 -16,-2 -5,-3 -8,-7 -10,-13 -2,-5 -1,-11 2,-16 2,-5 7,-8 12,-10 6,-2 12,-1 16,2 5,3 9,7 11,14l0 0zm-7 -2c-2,-4 -5,-7 -8,-9 -3,-1 -7,-1 -11,0 -4,1 -6,3 -8,6 -2,3 -3,7 -2,11l29 -8zm24 16l-4 2 -11 -35 -5 2 -1 -4 5 -2 0 -1c-2,-4 -1,-7 0,-10 2,-3 5,-4 9,-6l0 0 2 5c-3,0 -5,2 -6,3 -1,2 -1,4 0,7l0 1 8 -3 1 5 -8 2 10 34zm8 -26l13 -4 0 1c1,3 3,5 5,7 2,1 5,1 8,1 3,-1 5,-3 6,-6 1,-3 2,-6 0,-9 -1,-4 -2,-6 -5,-7 -3,-1 -6,-1 -10,0 0,0 -1,0 -1,0 -1,0 -1,1 -1,1l-4 -12c1,0 1,0 1,0 1,0 1,0 1,0 3,-1 5,-2 6,-4 1,-1 1,-3 0,-6 0,-2 -1,-3 -2,-4 -2,-1 -3,-1 -5,0 -2,0 -3,
 1 -4,3 0,1 0,3 0,5l-11 3c-2,-5 -2,-10 1,-14 2,-5 6,-8 11,-9 5,-2 9,-1 14,1 4,2 7,6 8,11 1,2 1,5 1,7 -1,3 -2,5 -4,7 5,1 8,2 11,5 3,2 5,6 6,10 1,3 1,6 1,9 0,3 -1,5 -2,8 -2,4 -3,6 -6,8 -2,2 -5,4 -8,5 -7,2 -14,1 -19,-1 -5,-3 -9,-8 -11,-16l0 0z"/>
+			<path d="M1563 2350c1,-3 3,-5 5,-7 2,-2 4,-3 7,-4 5,-1 10,-1 13,1 3,3 6,8 8,15l6 19 -5 1 -6 -20c-2,-5 -4,-9 -6,-10 -2,-2 -5,-2 -9,-1 -2,1 -4,2 -5,3 -2,1 -3,3 -3,5 -1,1 -1,3 -1,4 1,2 1,4 2,7l6 19 -5 1 -6 -21c-2,-5 -4,-8 -6,-9 -2,-2 -5,-2 -9,-1 -2,1 -4,2 -6,3 -1,2 -2,3 -3,5 0,1 0,3 0,4 0,2 1,4 2,7l5 19 -4 2 -12 -39 5 -2 1 5c1,-2 3,-4 4,-6 2,-1 4,-2 7,-3 3,-1 6,-1 8,0 3,0 6,1 7,3zm35 -17l5 -1 1 4c1,-2 3,-4 4,-5 2,-2 4,-3 7,-4 3,-1 5,-1 8,0 3,0 5,1 7,3 1,1 2,2 3,4 1,2 2,4 3,8l6 20 -5 2 -6 -22c-2,-5 -4,-8 -6,-9 -2,-2 -5,-2 -9,-1 -2,1 -4,2 -6,3 -1,2 -2,3 -3,5 0,2 0,3 0,4 0,2 1,4 2,8l5 18 -4 2 -12 -39zm49 7c1,4 4,7 8,10 3,2 7,2 12,1 4,-1 7,-4 9,-8 2,-3 2,-8 1,-12 -2,-5 -4,-8 -8,-10 -4,-2 -8,-3 -12,-1 -4,1 -7,3 -9,7 -2,4 -2,8 -1,13zm-5 1c-2,-5 -1,-11 2,-16 2,-5 6,-9 12,-10 5,-2 10,-1 16,2 5,2 8,6 10,12 1,6 1,11 -2,16 -2,6 -6,9 -12,11 -6,1 -11,1 -16,-2 -5,-3 -8,-7 -10,-13zm57 -21c1,4 3,6 6,8 3,2 6,2 9,1 3,-1 6,-3 7,-6 1,-2 2,-6 1,-9 -1,-4 -3,-6 -6,-8 -3,-1 -6,-2 -9,-1 -3,1 -5,3 -7
 ,6 -1,3 -2,6 -1,9zm-1 -48l13 -4 -8 27c1,0 2,-1 3,-1 0,0 1,-1 2,-1 5,-1 11,-1 16,3 5,3 9,8 11,14 0,3 1,6 1,9 -1,3 -1,6 -3,8 -1,4 -3,7 -6,9 -2,2 -6,4 -9,5 -4,1 -7,2 -10,1 -3,0 -7,-1 -9,-3 -3,-1 -6,-3 -8,-6 -2,-2 -3,-5 -4,-8 -1,-3 -2,-7 -1,-11 0,-3 1,-9 3,-15l9 -27z"/>
+			<path  d="M1550 2636l0 -31 6 -2 -2 43 -3 1 -18 -27 0 32 -3 1 -25 -35 5 -1 18 26 1 -32 3 -1 18 26zm11 -34l14 11 5 -17 6 -2 -8 23 19 16 -6 2 -14 -14 -6 20 -5 1 7 -24 -17 -15 5 -1zm23 -7l6 -2 21 28 3 -35 6 -2 -6 58 -5 1 1 -14 -26 -34zm73 20l-27 8 -1 -5 11 -35 -18 6 -1 -5 23 -7 2 5 -11 34 20 -6 2 5zm27 -57c-1,-3 -3,-6 -5,-7 -3,-2 -6,-3 -9,-2 -4,1 -6,3 -7,6 -2,3 -2,6 -1,9 1,4 3,6 6,8 2,2 5,2 8,1 4,-1 6,-3 7,-6 2,-3 2,-6 1,-9zm2 49l-14 4 9 -28c-1,1 -2,1 -3,1 -1,1 -2,1 -2,1 -6,2 -11,1 -16,-2 -6,-4 -9,-8 -11,-15 -1,-3 -1,-5 -1,-8 0,-3 1,-6 2,-9 2,-4 4,-7 6,-9 3,-2 6,-4 10,-5 3,-1 7,-1 10,-1 3,0 6,1 9,3 3,2 5,4 7,6 2,3 4,5 5,8 1,4 1,7 1,11 0,4 -2,9 -4,16l-8 27z"/>
+			<path d="M1215 2201l-47 0 0 -14 27 -24c2,-2 4,-4 5,-6 1,-2 2,-5 2,-7 0,-2 -1,-4 -2,-6 -2,-2 -4,-3 -7,-3 -3,0 -5,1 -7,3 -1,2 -2,4 -2,8l0 1 -14 0 0 0c0,-8 2,-14 6,-18 5,-4 10,-7 17,-7 7,1 12,3 17,7 4,4 6,10 6,16 0,3 -1,6 -3,10 -1,3 -4,6 -8,9l-20 18 30 0 0 13zm45 -20c0,-4 -2,-8 -5,-11 -3,-3 -6,-5 -10,-5 -5,0 -8,2 -12,5 -3,3 -4,7 -4,12 0,4 1,8 4,11 3,3 7,5 11,5 4,0 8,-2 11,-5 3,-3 4,-7 5,-12zm-1 14c-1,3 -3,4 -6,6 -3,1 -6,2 -9,1 -6,0 -11,-2 -15,-6 -4,-4 -6,-9 -6,-15 0,-6 3,-11 7,-15 4,-4 9,-6 15,-6 3,0 6,1 8,2 3,2 5,3 7,6l0 -7 5 0 -1 41 -5 0 0 -7zm19 -47l0 17 0 3c2,-2 4,-4 7,-5 3,-2 6,-2 9,-2 5,0 10,2 14,6 4,4 6,9 6,15 0,6 -2,11 -6,15 -5,4 -10,6 -16,6 -3,0 -5,-1 -8,-2 -2,-1 -4,-3 -7,-5l0 6 -5 0 1 -54 5 0zm0 34c0,4 1,8 4,11 3,4 7,5 11,5 4,0 8,-1 11,-4 3,-4 4,-8 4,-12 0,-5 -1,-8 -4,-12 -3,-3 -7,-4 -11,-4 -4,0 -8,1 -11,4 -3,4 -4,7 -4,12zm74 -7c-1,-3 -3,-5 -5,-7 -3,-1 -5,-2 -9,-2 -4,0 -7,1 -10,5 -3,3 -5,7 -5,11 0,5 2,9 5,12 2,3 6,5 10,5 3,0 6,-1 9,-3 2,-1 4,-3 5,-6l6 0c-2,4 -4,8 -
 8,10 -3,3 -7,4 -12,4 -5,0 -10,-3 -14,-7 -4,-4 -6,-9 -6,-15 0,-6 2,-11 6,-15 4,-4 9,-6 15,-6 4,0 8,1 12,4 3,2 5,6 7,10l-6 0z"/>
+			<path d="M1229 2394l0 12 -24 0 -3 12c2,-1 3,-1 5,-2 1,0 3,0 5,0 7,0 12,2 17,7 4,5 6,11 6,18 0,3 0,6 -1,9 -2,3 -3,5 -5,8 -3,3 -6,5 -9,6 -3,2 -7,2 -10,2 -7,0 -13,-2 -17,-6 -5,-5 -7,-11 -8,-18l13 1c1,3 2,5 4,7 2,2 5,3 8,3 3,1 6,-1 8,-3 2,-2 3,-6 3,-9 0,-4 -1,-7 -3,-9 -2,-2 -5,-4 -9,-4 -2,0 -4,1 -5,2 -2,0 -3,2 -4,3l-12 -2 8 -37 33 0zm20 26l-5 0 0 -8 5 0 0 8zm0 5l0 40c0,5 -1,9 -2,10 -2,2 -4,3 -7,3l-1 0 0 -5c2,0 3,0 4,-1 0,0 1,-2 1,-6l0 -41 5 0zm13 40l-5 0 1 -53 5 0 0 32 14 -19 6 0 -14 19 17 22 -6 0 -17 -22 -1 21zm26 1l1 -54 5 0 -1 54 -5 0z"/>
+			<path d="M1212 2646c0,2 0,4 1,5 2,2 3,2 5,2 2,0 4,0 5,-2 1,-1 2,-3 2,-5 0,-2 -1,-4 -2,-5 -1,-1 -3,-2 -5,-2 -1,0 -3,1 -4,2 -2,1 -2,3 -2,5zm-4 32c0,3 1,6 3,8 2,2 4,3 7,3 3,0 5,-1 7,-3 2,-2 3,-5 3,-8 0,-3 -1,-5 -3,-7 -2,-2 -4,-3 -7,-3 -3,0 -5,1 -7,3 -2,2 -3,4 -3,7zm-2 -18c-3,-2 -5,-4 -6,-6 -1,-3 -2,-5 -2,-8 0,-6 2,-10 6,-14 4,-3 9,-5 14,-5 6,0 11,2 15,6 4,3 6,8 6,13 0,3 -1,6 -2,8 -2,2 -4,4 -7,6 4,2 7,5 9,8 2,3 3,6 3,10 0,7 -3,12 -7,17 -5,4 -11,6 -18,6 -6,0 -12,-2 -16,-7 -5,-4 -7,-10 -7,-16 0,-4 1,-8 3,-11 2,-2 5,-5 9,-7zm48 40l1 -35 -8 0 0 -5 8 0 0 -13 5 0 0 13 8 0 0 5 -8 0 0 35 -6 0zm18 -40l5 0 0 21c-1,6 0,10 2,12 2,2 5,3 9,4 2,0 4,-1 6,-2 2,-1 3,-2 4,-4 1,-1 1,-2 2,-4 0,-1 0,-3 0,-7l0 -20 5 0 0 41 -5 -1 0 -4c-2,2 -3,3 -5,4 -2,1 -5,1 -7,1 -6,0 -10,-1 -13,-4 -2,-4 -4,-9 -4,-16l1 -21zm57 41l-5 0 -15 -41 5 0 13 33 13 -32 6 0 -17 40z"/>
+			<path d="M1233 2866l0 21c0,5 1,8 2,10 2,3 5,4 8,4 4,0 7,-1 9,-3 2,-3 3,-6 3,-11l0 -22c0,-2 0,-3 0,-5 -1,-1 -1,-1 -1,-2 -1,-2 -3,-3 -4,-4 -2,-1 -4,-2 -6,-2 -4,0 -6,1 -8,4 -2,2 -3,5 -3,10zm-14 0c0,-5 1,-8 1,-10 1,-3 2,-5 4,-7 2,-3 5,-6 8,-7 4,-2 8,-2 12,-2 4,0 8,1 12,2 3,2 6,4 9,8 1,1 2,4 3,6 1,3 1,6 1,11l0 21c-1,4 -1,7 -2,10 0,2 -1,4 -3,6 -3,4 -5,6 -9,7 -3,2 -7,3 -12,3 -4,0 -8,-1 -11,-3 -4,-2 -7,-4 -9,-7 -2,-2 -3,-4 -3,-7 -1,-3 -1,-6 -1,-10l0 -21zm91 61l0 4 -38 -1 0 -3 38 0z"/>
+			<path d="M1453 3013l3 9 7 -6 -3 -9 -7 6zm-14 -18l6 -4 6 16 7 -6 -6 -16 5 -4 6 16 8 -7 3 6 -9 7 4 9 8 -7 3 6 -9 7 6 16 -6 5 -6 -16 -7 6 6 16 -5 4 -6 -16 -9 7 -2 -6 9 -7 -4 -9 -9 7 -2 -6 9 -8 -6 -16zm67 -54l6 -5 27 4 -6 5 -20 -2 -2 20 -6 5 1 -27z"/>
+			<path d="M1029 2952l-11 4 -2 -6 11 -4 -7 -8 5 -4 6 9 7 -9 5 3 -6 9 10 3 -2 6 -10 -3 0 11 -6 1 0 -12zm63 29l5 4 -11 16 16 10 -3 5 -16 -10 -11 16 -5 -4 11 -16 -16 -10 4 -5 15 10 11 -16z"/>
+		</g>
+		<g id="kreise_hg" fill="#cccccc">
+			<path d="M1089 617c22,-20 107,21 166,23 58,1 149,-42 170,-25 20,18 -73,69 -167,67 -86,-2 -192,-45 -169,-65zm83 13c36,12 63,29 60,38 -3,8 -34,6 -70,-6 -36,-12 -63,-29 -60,-38 3,-8 34,-6 70,6zm170 0c-36,12 -63,29 -60,38 3,8 34,6 70,-6 36,-12 63,-29 60,-38 -3,-8 -34,-6 -70,6z"/>
+			<path d="M1202 585c7,-6 40,-1 58,-1 17,1 42,-5 49,1 6,5 -21,34 -50,33 -26,0 -63,-27 -57,-33zm54 4c13,0 23,5 23,11 0,5 -10,10 -23,10 -13,0 -23,-5 -23,-10 0,-6 10,-11 23,-11z"/>
+		 </g>
+		<g id="kreise">
+			<path fill="black" d="M1172 630c36,12 63,29 60,38 -3,8 -34,6 -70,-6 -36,-12 -63,-29 -60,-38 3,-8 34,-6 70,6z"/>
+			<path fill="black" d="M1342 630c-36,12 -63,29 -60,38 3,8 34,6 70,-6 36,-12 63,-29 60,-38 -3,-8 -34,-6 -70,6z"/>
+			<ellipse fill="black" cx="1256" cy="600" rx="23" ry="10"/>
+		</g>
+	 
+<!--*************************************************************************************-->
+ <!--***********************************************FILTER/PATTERN
+ ****************************************************************************************-->
+	
+	
+		<pattern id="pat" patternUnits="userSpaceOnUse" x="0" y="0" width="5" height="5" viewBox="0 0 10 10">
+			<rect x="0" y="0" width="5" height="5" fill="black"/>
+			 <circle cx="5" cy="5" r="4" fill="none" stroke="green" stroke-width="0.5"/>
+		 </pattern>
+		<pattern id="pat2" patternUnits="userSpaceOnUse" x="0" y="0" width="5" height="5" viewBox="0 0 10 10">
+			 <rect x="0" y="0" width="5" height="5" fill="black"/>
+			 <circle cx="5" cy="5" r="4" fill="none" stroke="yellowgreen" stroke-width="0.5"/>
+		 </pattern>
+		<filter id="licht">
+			<feGaussianBlur stdDeviation="5" in="SourceAlpha" result="bump"/>
+			<feSpecularLighting in="bump" surfaceScale="5" lighting-color="white" result="difOut" specularConstant="5" specularExponent="30">
+				<fePointLight id="pointl" x="4941.18" y="4588.24" z="4823.53"/>
+			</feSpecularLighting>
+			<feComposite in="difOut" in2="SourceAlpha" operator="in" result="specOut"/> 
+			<feComposite  id="fc"  in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/> 
+			<feMerge> 
+			<feMergeNode in="offsetBlur"/> 
+			<feMergeNode in="litPaint"/> 
+			</feMerge>  
+		</filter>
+		<filter id="licht2">
+			<feGaussianBlur stdDeviation="9" in="SourceAlpha" result="bump"/>
+			<feSpecularLighting in="bump" surfaceScale="15" lighting-color="white" result="difOut" specularConstant="5" specularExponent="30">
+				<fePointLight id="pointl" x="4941.18" y="4588.24" z="4823.53"/>
+			</feSpecularLighting>
+			<feComposite in="difOut" in2="SourceAlpha" operator="in" result="specOut"/> 
+			<feComposite  id="fc"  in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="0.3" k4="0" result="litPaint"/> 
+			<feMerge> 
+			<feMergeNode in="offsetBlur"/> 
+			<feMergeNode in="litPaint"/> 
+			</feMerge>  
+		</filter>
+		<filter id="shadow">
+			<feGaussianBlur stdDeviation="40" in="SourceAlpha" result="bump"/>
+			<feOffset dx="30" dy="30" in="bump"/>
+		</filter>
+		<filter id="holz">
+			<feGaussianBlur stdDeviation="5.8" result="result9" in="SourceAlpha"/>
+			<feTurbulence baseFrequency="0.00115,0.0745" result="result1" type="turbulence" numOctaves="0.225" stitchTiles="noStitch" seed="8.025"/>
+			<feColorMatrix type="matrix" result="result4" values="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0" in="result1"/>
+			<feColorMatrix type="matrix" result="result3" values="0,0,0,0,0.01666666666666672,0,0,0,0,0,0,0,0,0,0,0,0,0,0.8916666666666666,0" in="result1"/>
+			<feDisplacementMap result="result2" in="result3" in2="result1" scale="49" xChannelSelector="A" yChannelSelector="A"/>
+			<feComposite operator="atop" result="result6" in="result4" in2="result2"/>
+			<feColorMatrix type="matrix" result="result7" values="0,0.025000000000000022,0.008333333333333303,0.375,0,0,0,0,0.07500000000000006,0,0,0,0,0.033333333333333326,0,0,0,0,0,1" in="result6"/>
+			<feComposite operator="arithmetic" result="result10" in="result9" in2="result7" k2="1.96" k3="1.51"/>
+			<feComposite operator="in" result="result11" in="result10" in2="SourceAlpha"/>
+			<feOffset result="result12" in="result9" dx="7.5" dy="8.9"/>
+			<feComposite operator="arithmetic" result="result13" in="result11" in2="result12" k3="1.4" k2="1.39" k1="0.46"/>
+		</filter>
+		<filter id="Leopard">
+			<feColorMatrix type="matrix" result="result3" values="1,0.3285714285714286,0,0,0,0,0,0,0.2571428571428571,0,0,0,1,0,0,1,1,0,0,0" in="result2"/>
+			<feTurbulence baseFrequency="0.017657657657657657,0.01357357357357357" result="result1" type="turbulence" numOctaves="2.46667" seed="20.2667" stitchTiles="noStitch"/>
+			<feComponentTransfer result="result2" in="result1">
+				<feFuncR type="table" tableValues="0.6142857142857143,0.8571428571428572,1,1" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncG type="discrete" tableValues="0.9285714285714286,0.05714285714285716,0.5142857142857142,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncB type="discrete" tableValues="0,0,0,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="20"/>
+				<feFuncA type="discrete" tableValues="1,1,1,1" amplitude="0.6" exponent="-1" offset="1" slope="20"/>
+			</feComponentTransfer>
+			<feColorMatrix type="matrix" result="result4" values="0,1,0,0,0,0,0.3571428571428572,0,0,0,0,0,0.014285714285714346,0,0,0,0,0,0,1" in="result2"/>
+			<feComposite operator="in" result="result5" in="result4" in2="SourceAlpha" k1="0.1" k2="0.5" k3="0.5" k4="0"/>
+		</filter>
+		<filter id="Zebra">
+			<feTurbulence baseFrequency="0.019759759759759759,0.0095075075075075074" result="result1" type="fractalNoise" numOctaves="0" seed="35.2" stitchTiles="noStitch"/>
+			<feComponentTransfer result="result2" in="result1"><feFuncR type="discrete" tableValues="0,0,0,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncG type="discrete" tableValues="0,0,0,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncB type="discrete" tableValues="0,0.6285714285714286,0,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncA type="table" tableValues="1,1,1,1" amplitude="1" exponent="1" offset="0" slope="1"/>
+			</feComponentTransfer>
+			<feColorMatrix type="matrix" result="result3" values="0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,1" in="result2"/>
+			<feComposite operator="in" result="result4" in="result3" in2="SourceAlpha" k1="0.1" k2="0.5" k3="0.5" k4="0"/>
+		</filter>
+		<filter id="funk">
+			<feTurbulence baseFrequency="0.013753753753753754,0.013753753753753754" result="result1" type="turbulence" numOctaves="0" seed="53.6" stitchTiles="noStitch"/>
+			<feComponentTransfer result="result2" in="result1">
+				<feFuncR type="gamma" tableValues="0,0,0,0" amplitude="0.257143" exponent="-0.485714" offset="-1" slope="1" intercept="0"/>
+				<feFuncG type="gamma" tableValues="0,0,0,0" amplitude="0.314286" exponent="-0.428571" offset="-1" slope="1" intercept="0"/>
+				<feFuncB type="gamma" tableValues="0,0,0,0" amplitude="0.342857" exponent="-0.342857" offset="-1" slope="1" intercept="0"/>
+				<feFuncA type="table" tableValues="1,1,1,1" amplitude="1" exponent="1" offset="0" slope="1"/>
+			</feComponentTransfer>
+			<feComposite operator="in" result="result3" in="result2" in2="SourceAlpha" k1="0.1" k2="0.5" k3="0.466667" k4="0"/>
+		</filter>
+		<filter id="blatt">
+			<feTurbulence baseFrequency="0.07057057057057057,0.0015015015015015014" result="result1" type="turbulence" numOctaves="0" seed="0" stitchTiles="stitch"/>
+			<feColorMatrix type="matrix" result="result2" values="1,1,0,0,1,1,0,1,0,0,1,1,1,1,0,0,0,0,0,1" in="result1"/>
+			<feComponentTransfer result="result4" in="result2">
+				<feFuncR type="gamma" tableValues="1,0,0,0" amplitude="-1" exponent="-1" offset="-1" slope="1" intercept="0"/>
+				<feFuncG type="gamma" tableValues="1,0.44285714285714284,0,0" amplitude="1" exponent="1" offset="0" slope="1" intercept="0"/>
+				<feFuncB type="gamma" tableValues="1,0,0,0" amplitude="-1" exponent="-1" offset="-1" slope="1" intercept="0"/>
+				<feFuncA type="gamma" tableValues="1,0,0,0" amplitude="1" exponent="1" offset="1" slope="1"/>
+			</feComponentTransfer><feComposite operator="in" result="result3" in="result4" in2="SourceGraphic" k1="0.1" k2="0.5" k3="0.5" k4="0"/>
+		</filter>
+
+
+	</defs>
+  <!--*************************************************************************************-->
+ <!--***********************************************/DEFS
+ ****************************************************************************************-->
+		
+	<g filter="url(#shadow)">		
+		<use xlink:href="#hg"/>
+		<use xlink:href="#hg_unten"/>
+		</g>
+
+		<use xlink:href="#hg" filter="url(#licht2)"/>
+		<use xlink:href="#hg_unten" filter="url(#licht)"/>
+
+	
+	<use xlink:href="#hg_oben" filter="url(#licht)"/>
+	<use xlink:href="#linien" filter="url(#licht)"/>
+
+	<use xlink:href="#display" fill="green"/>
+	<use xlink:href="#display" fill="url(#pat)"/>
+	<use xlink:href="#knopf_oben" filter="url(#licht)"/>
+	<use xlink:href="#knopf_unten" filter="url(#licht)"/>
+	<use xlink:href="#knopf_text_oben"/>
+	<use xlink:href="#knopf_text_unten"/>
+	<use xlink:href="#kreise_hg" filter="url(#licht)"/>
+	<use xlink:href="#kreise"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  <metadata>
+    <rdf:RDF 
+     xmlns="http://web.resource.org/cc/";
+     xmlns:dc="http://purl.org/dc/elements/1.1/";
+     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";>
+      <Work rdf:about="">
+        <dc:title>mobile phone</dc:title>
+	<dc:description></dc:description>
+        <dc:subject>
+          <rdf:Bag>
+            <rdf:li>office</rdf:li>
+            <rdf:li>communication</rdf:li>
+          </rdf:Bag>
+        </dc:subject>
+        <dc:publisher>
+           <Agent rdf:about="">
+             <dc:title>Open Clip Art Library</dc:title>
+           </Agent>
+         </dc:publisher>
+         <dc:creator>
+           <Agent rdf:about="">
+             <dc:title>Juliane Krug</dc:title>
+           </Agent>
+        </dc:creator>
+         <dc:rights>
+           <Agent rdf:about="">
+             <dc:title></dc:title>
+           </Agent>
+        </dc:rights>
+        <dc:date></dc:date>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <license rdf:resource="Public Domain">
+	  <dc:date>48</dc:date>
+	</license>
+        <dc:language>en</dc:language>
+      </Work>
+
+      <License rdf:about="Public Domain">
+         <permits rdf:resource="http://web.resource.org/cc/Reproduction"; />
+         <permits rdf:resource="http://web.resource.org/cc/Distribution"; />
+         <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"; />
+      </License>
+
+
+    </rdf:RDF>
+  </metadata>
+</svg>



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