[lasem] use: detect circular references.



commit 9d0fb4eac5fcf49e817e8e60420b864fbdd4547a
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Wed May 4 22:53:59 2011 +0200

    use: detect circular references.

 src/lsmsvguseelement.c                             |   22 ++++++++++++++++++++
 src/lsmsvguseelement.h                             |    7 ++++++
 tests/data/svg/misc/circular-reference-use.svg     |   15 +++++++++++++
 .../circular-reference.svg                         |    0
 .../pattern-self-reference.svg                     |    0
 .../radial-gradient-self-reference.svg             |    0
 6 files changed, 44 insertions(+), 0 deletions(-)
---
diff --git a/src/lsmsvguseelement.c b/src/lsmsvguseelement.c
index cda706b..c3ddb14 100644
--- a/src/lsmsvguseelement.c
+++ b/src/lsmsvguseelement.c
@@ -83,10 +83,17 @@ lsm_svg_use_element_render (LsmSvgElement *self, LsmSvgView *view)
 	LsmSvgMatrix matrix;
 	double x, y;
 
+	if (use_element->flags & LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_RENDER) {
+		lsm_debug ("render", "[LsmSvgUseElement::render] Circular reference");
+		return;
+	}
+
 	element = _get_used_element (use_element, "render");
 	if (element == NULL)
 		return;
 
+	use_element->flags |= LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_RENDER;
+
 	x = lsm_svg_view_normalize_length (view, &use_element->x.length,
 					   LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
 	y = lsm_svg_view_normalize_length (view, &use_element->y.length,
@@ -98,6 +105,8 @@ lsm_svg_use_element_render (LsmSvgElement *self, LsmSvgView *view)
 	lsm_svg_element_render (LSM_SVG_ELEMENT (element), view);
 
 	lsm_svg_view_pop_matrix (view);
+
+	use_element->flags &= ~LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_RENDER;
 }
 
 static void
@@ -108,6 +117,15 @@ lsm_svg_use_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExten
 	LsmSvgMatrix matrix;
 	double x, y;
 
+	if (use_element->flags & LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_GET_EXTENTS) {
+		lsm_debug ("render", "[LsmSvgUseElement::get_extents] Circular reference");
+		extents->x1 = 0;
+		extents->y1 = 0;
+		extents->x2 = 0;
+		extents->y2 = 0;
+		return;
+	}
+
 	element = _get_used_element (use_element, "render");
 	if (element == NULL) {
 		extents->x1 = 0;
@@ -117,6 +135,8 @@ lsm_svg_use_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExten
 		return;
 	}
 
+	use_element->flags |= LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_GET_EXTENTS;
+
 	x = lsm_svg_view_normalize_length (view, &use_element->x.length,
 					   LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
 	y = lsm_svg_view_normalize_length (view, &use_element->y.length,
@@ -137,6 +157,8 @@ lsm_svg_use_element_get_extents (LsmSvgElement *self, LsmSvgView *view, LsmExten
 					       &extents->x2, &extents->y2);
 
 	lsm_svg_view_pop_matrix (view);
+
+	use_element->flags &= ~LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_GET_EXTENTS;
 }
 
 /* LsmSvgUseElement implementation */
diff --git a/src/lsmsvguseelement.h b/src/lsmsvguseelement.h
index 834293e..68f8126 100644
--- a/src/lsmsvguseelement.h
+++ b/src/lsmsvguseelement.h
@@ -28,6 +28,11 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+	LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_RENDER =		1 << 0,
+	LSM_SVG_USE_ELEMENT_FLAGS_IN_USE_FOR_GET_EXTENTS =	1 << 1
+} LsmSvgUseElementFlags;
+
 #define LSM_TYPE_SVG_USE_ELEMENT             (lsm_svg_use_element_get_type ())
 #define LSM_SVG_USE_ELEMENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_USE_ELEMENT, LsmSvgUseElement))
 #define LSM_SVG_USE_ELEMENT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_USE_ELEMENT, LsmSvgUseElementClass))
@@ -46,6 +51,8 @@ struct _LsmSvgUseElement {
 	LsmSvgLengthAttribute	height;
 
 	LsmAttribute		href;
+
+	LsmSvgUseElementFlags	flags;
 };
 
 struct _LsmSvgUseElementClass {
diff --git a/tests/data/svg/misc/circular-reference-use.svg b/tests/data/svg/misc/circular-reference-use.svg
new file mode 100644
index 0000000..59ec9d5
--- /dev/null
+++ b/tests/data/svg/misc/circular-reference-use.svg
@@ -0,0 +1,15 @@
+<svg xmlns='http://www.w3.org/2000/svg'
+     xmlns:xlink='http://www.w3.org/1999/xlink'
+     version='1.2' baseProfile='tiny'>
+
+  <title>Example of a circular reference with 'use'</title>
+
+  <g id='a'>
+    <text>ABC</text>
+    <use xlink:href='#b'/>
+  </g>
+  <g id='b'>
+    <text>DEF</text>
+    <use xlink:href='#a'/>
+  </g>
+</svg>
diff --git a/tests/data/svg/ignore-crashers/circular-reference.svg b/tests/data/svg/misc/circular-reference.svg
similarity index 100%
rename from tests/data/svg/ignore-crashers/circular-reference.svg
rename to tests/data/svg/misc/circular-reference.svg
diff --git a/tests/data/svg/ignore-crashers/pattern-self-reference.svg b/tests/data/svg/misc/pattern-self-reference.svg
similarity index 100%
rename from tests/data/svg/ignore-crashers/pattern-self-reference.svg
rename to tests/data/svg/misc/pattern-self-reference.svg
diff --git a/tests/data/svg/ignore-crashers/radial-gradient-self-reference.svg b/tests/data/svg/misc/radial-gradient-self-reference.svg
similarity index 100%
rename from tests/data/svg/ignore-crashers/radial-gradient-self-reference.svg
rename to tests/data/svg/misc/radial-gradient-self-reference.svg



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