[lasem] <svg:mask> Start the implementation. Create a new mask attribute bag.



commit 48ef6e70278997b28931e60d4ea8f5314a139832
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date:   Wed Jun 24 17:27:53 2009 +0200

    <svg:mask> Start the implementation. Create a new mask attribute bag.
    
    The new mask attribute bag also contains the opacity property.

 src/Makefile.am             |    2 +
 src/lsmsvg.h                |    1 +
 src/lsmsvgattributebags.c   |   46 ++++++++--
 src/lsmsvgattributebags.h   |    9 ++-
 src/lsmsvgcircleelement.c   |    1 -
 src/lsmsvgdocument.c        |    3 +
 src/lsmsvgelement.c         |    5 +
 src/lsmsvgellipseelement.c  |    1 -
 src/lsmsvggraphic.c         |   46 +++++------
 src/lsmsvggraphic.h         |    4 +-
 src/lsmsvglineelement.c     |    1 -
 src/lsmsvgmaskelement.c     |  130 +++++++++++++++++++++++++++
 src/lsmsvgmaskelement.h     |   60 +++++++++++++
 src/lsmsvgpathelement.c     |    1 -
 src/lsmsvgpolygonelement.c  |    1 -
 src/lsmsvgpolylineelement.c |    1 -
 src/lsmsvgrectelement.c     |    1 -
 src/lsmsvgtextelement.c     |    1 -
 src/lsmsvgview.c            |  202 +++++++++++++++++++++++++-----------------
 src/lsmsvgview.h            |   23 +++--
 20 files changed, 401 insertions(+), 138 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 58d7bd1..dc76bd8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,6 +83,7 @@ liblasem_la_SOURCES =				\
 	lsmsvgradialgradientelement.c		\
 	lsmsvgstopelement.c			\
 	lsmsvgpatternelement.c			\
+	lsmsvgmaskelement.c			\
 	lsmsvgenums.c				\
 	lsmsvgattributes.c			\
 	lsmsvgattributebags.c			\
@@ -165,6 +166,7 @@ liblasem_la_HEADERS = \
 	lsmsvgradialgradientelement.h		\
 	lsmsvgstopelement.h			\
 	lsmsvgpatternelement.h			\
+	lsmsvgmaskelement.h			\
 	lsmsvgenums.h				\
 	lsmsvgattributes.h			\
 	lsmsvgattributebags.h			\
diff --git a/src/lsmsvg.h b/src/lsmsvg.h
index 8277921..43bc421 100644
--- a/src/lsmsvg.h
+++ b/src/lsmsvg.h
@@ -49,6 +49,7 @@ typedef struct _LsmSvgLinearGradientElement LsmSvgLinearGradientElement;
 typedef struct _LsmSvgRadialGradientElement LsmSvgRadialGradientElement;
 typedef struct _LsmSvgStopElement LsmSvgStopElement;
 typedef struct _LsmSvgPatternElement LsmSvgPatternElement;
+typedef struct _LsmSvgMaskElement LsmSvgMaskElement;
 
 typedef struct _LsmSvgView LsmSvgView;
 typedef struct _LsmSvgStyle LsmSvgStyle;
diff --git a/src/lsmsvgattributebags.c b/src/lsmsvgattributebags.c
index b34d68e..dfadb82 100644
--- a/src/lsmsvgattributebags.c
+++ b/src/lsmsvgattributebags.c
@@ -22,6 +22,44 @@
 #include <lsmsvgattributebags.h>
 
 static void *
+lsm_svg_mask_attribute_bag_init (void)
+{
+	LsmSvgMaskAttributeBag *mask;
+
+	mask = g_new0 (LsmSvgMaskAttributeBag, 1);
+	return mask;
+}
+
+static void
+lsm_svg_mask_attribute_bag_finalize (void *bag)
+{
+	g_free (bag);
+}
+
+static const LsmDomAttributeBagClass lsm_svg_mask_attribute_bag_class =
+{
+	.init = lsm_svg_mask_attribute_bag_init,
+	.finalize = lsm_svg_mask_attribute_bag_finalize
+};
+
+void
+lsm_dom_attribute_map_add_mask_attribute_bag (LsmDomAttributeMap *map, ptrdiff_t bag_offset)
+{
+	lsm_dom_attribute_map_add_bag_attribute (map, "opacity",
+						 offsetof (LsmSvgMaskAttributeBag, opacity),
+						 NULL,
+						 bag_offset, &lsm_svg_mask_attribute_bag_class);
+	lsm_dom_attribute_map_add_bag_attribute (map, "clip-path",
+						 offsetof (LsmSvgMaskAttributeBag, clip_path),
+						 NULL,
+						 bag_offset, &lsm_svg_mask_attribute_bag_class);
+	lsm_dom_attribute_map_add_bag_attribute (map, "clip-rule",
+						 offsetof (LsmSvgMaskAttributeBag, clip_rule),
+						 NULL,
+						 bag_offset, &lsm_svg_mask_attribute_bag_class);
+}
+
+static void *
 lsm_svg_fill_attribute_bag_init (void)
 {
 	LsmSvgFillAttributeBag *fill;
@@ -61,14 +99,6 @@ lsm_dom_attribute_map_add_fill_attribute_bag (LsmDomAttributeMap *map, ptrdiff_t
 						 offsetof (LsmSvgFillAttributeBag, opacity),
 						 NULL,
 						 bag_offset, &lsm_svg_fill_attribute_bag_class);
-	lsm_dom_attribute_map_add_bag_attribute (map, "clip-path",
-						 offsetof (LsmSvgFillAttributeBag, clip_path),
-						 NULL,
-						 bag_offset, &lsm_svg_fill_attribute_bag_class);
-	lsm_dom_attribute_map_add_bag_attribute (map, "clip-rule",
-						 offsetof (LsmSvgFillAttributeBag, clip_rule),
-						 NULL,
-						 bag_offset, &lsm_svg_fill_attribute_bag_class);
 }
 
 static void *
diff --git a/src/lsmsvgattributebags.h b/src/lsmsvgattributebags.h
index d7dfdd7..e84f07b 100644
--- a/src/lsmsvgattributebags.h
+++ b/src/lsmsvgattributebags.h
@@ -28,11 +28,15 @@
 G_BEGIN_DECLS
 
 typedef struct {
+	LsmDomAttribute clip_path;
+	LsmDomEnumAttribute clip_rule;
+	LsmSvgDoubleAttribute opacity;
+} LsmSvgMaskAttributeBag;
+
+typedef struct {
 	LsmSvgPaintAttribute paint;
 	LsmDomEnumAttribute rule;
 	LsmDomDoubleAttribute opacity;
-	LsmDomAttribute clip_path;
-	LsmDomEnumAttribute clip_rule;
 } LsmSvgFillAttributeBag;
 
 typedef struct {
@@ -60,6 +64,7 @@ typedef struct {
 	LsmSvgDoubleAttribute opacity;
 } LsmSvgStopAttributeBag;
 
+void 	lsm_dom_attribute_map_add_mask_attribute_bag 		(LsmDomAttributeMap *map, ptrdiff_t bag_offset);
 void 	lsm_dom_attribute_map_add_fill_attribute_bag 		(LsmDomAttributeMap *map, ptrdiff_t bag_offset);
 void 	lsm_dom_attribute_map_add_stroke_attribute_bag		(LsmDomAttributeMap *map, ptrdiff_t bag_offset);
 void 	lsm_dom_attribute_map_add_transform_attribute_bag	(LsmDomAttributeMap *map, ptrdiff_t bag_offset);
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index b0a333b..5371a7d 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -111,7 +111,6 @@ lsm_svg_circle_element_class_init (LsmSvgCircleElementClass *s_rect_class)
 	s_element_class->update = lsm_svg_circle_element_update;
 
 	s_graphic_class->graphic_render = lsm_svg_circle_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgdocument.c b/src/lsmsvgdocument.c
index 941b389..3c41c33 100644
--- a/src/lsmsvgdocument.c
+++ b/src/lsmsvgdocument.c
@@ -40,6 +40,7 @@
 #include <lsmsvgradialgradientelement.h>
 #include <lsmsvgstopelement.h>
 #include <lsmsvgpatternelement.h>
+#include <lsmsvgmaskelement.h>
 #include <lsmsvgview.h>
 #include <string.h>
 
@@ -86,6 +87,8 @@ lsm_svg_document_create_element (LsmDomDocument *document, const char *tag_name)
 		node = lsm_svg_stop_element_new ();
 	else if (strcmp (tag_name, "pattern") == 0)
 		node = lsm_svg_pattern_element_new ();
+	else if (strcmp (tag_name, "mask") == 0)
+		node = lsm_svg_mask_element_new ();
 	else if (strcmp (tag_name, "use") == 0)
 		node = lsm_svg_use_element_new ();
 	else if (strcmp (tag_name, "image") == 0)
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index daeea96..26299b2 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -138,6 +138,9 @@ lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
 
 	g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
 
+
+	lsm_svg_view_push_element (view, element);
+
 	element_class = LSM_SVG_ELEMENT_GET_CLASS (element);
 	if (element_class->render != NULL) {
 		lsm_debug ("[LsmSvgElement::render] Render %s (%s)",
@@ -146,6 +149,8 @@ lsm_svg_element_render (LsmSvgElement *element, LsmSvgView *view)
 
 		element_class->render (element, view);
 	}
+
+	lsm_svg_view_pop_element (view);
 }
 
 void
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index e26fc78..17f7783 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -112,7 +112,6 @@ lsm_svg_ellipse_element_class_init (LsmSvgEllipseElementClass *s_rect_class)
 	s_element_class->update = lsm_svg_ellipse_element_update;
 
 	s_graphic_class->graphic_render = lsm_svg_ellipse_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvggraphic.c b/src/lsmsvggraphic.c
index d32abb8..75ec2c5 100644
--- a/src/lsmsvggraphic.c
+++ b/src/lsmsvggraphic.c
@@ -92,14 +92,19 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
 
 	lsm_svg_color_attribute_parse (&graphic->color, &parent_style->color, &parent_style->color);
 
-	default_opacity = 1.0;
-	lsm_svg_double_attribute_parse (&graphic->opacity, &default_opacity); /* FIXME handle inherit */
 
 	if (graphic->text != NULL) {
 		lsm_dom_string_attribute_parse (&graphic->text->font_family, &parent_style->text.font_family);
 		lsm_svg_length_attribute_parse (&graphic->text->font_size, &parent_style->text.font_size);
 	}
 
+	if (graphic->mask != NULL) {
+		lsm_svg_fill_rule_attribute_parse (&graphic->mask->clip_rule, &parent_style->clip.rule);
+		default_opacity = 1.0;
+		/* FIXME handle inherit */
+		lsm_svg_double_attribute_parse (&graphic->mask->opacity, &default_opacity);
+	}
+
 	if (graphic->fill != NULL) {
 		lsm_debug ("[LsmSvgGraphic::update] fill");
 
@@ -107,7 +112,6 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
 					       &graphic->color.value);
 		lsm_svg_fill_rule_attribute_parse (&graphic->fill->rule, &parent_style->fill.rule);
 		lsm_dom_double_attribute_parse (&graphic->fill->opacity, &parent_style->fill.opacity);
-		lsm_svg_fill_rule_attribute_parse (&graphic->fill->clip_rule, &parent_style->clip.rule);
 	}
 
 	if (graphic->stroke != NULL) {
@@ -141,14 +145,21 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
 static void
 _graphic_render (LsmSvgElement *self, LsmSvgView *view)
 {
+	LsmSvgGraphic *graphic = LSM_SVG_GRAPHIC (self);
 	LsmDomNode *node;
 
 	lsm_debug ("[LsmSvgGraphic::_graphic_render]");
 
+	if (graphic->mask != NULL)
+		lsm_svg_view_push_group_opacity (view);
+
 	for (node = LSM_DOM_NODE (self)->first_child; node != NULL; node = node->next_sibling) {
 		if (LSM_IS_SVG_ELEMENT (node))
 		    lsm_svg_element_render (LSM_SVG_ELEMENT (node), view);
 	}
+
+	if (graphic->mask != NULL)
+		lsm_svg_view_pop_group_opacity (view);
 }
 
 static void
@@ -159,20 +170,10 @@ lsm_svg_graphic_render (LsmSvgElement *self, LsmSvgView *view)
 	if (graphic->transform != NULL)
 		lsm_svg_view_push_matrix (view, &graphic->transform->transform.matrix);
 
-	lsm_svg_view_push_opacity (view, graphic->opacity.value,
-				   LSM_SVG_GRAPHIC_GET_CLASS (graphic)->late_opacity_handling);
-
-	if (graphic->fill != NULL) {
+	if (graphic->mask != NULL)
+		lsm_svg_view_push_mask_attributes (view, graphic->mask);
+	if (graphic->fill != NULL)
 		lsm_svg_view_push_fill_attributes (view, graphic->fill);
-
-		if (graphic->fill->clip_path.value != NULL) {
-			LsmExtents extents;
-
-			lsm_svg_element_get_extents (self, view, &extents);
-			lsm_svg_view_push_clip (view, graphic->fill->clip_path.value,
-						graphic->fill->clip_rule.value, &extents);
-		}
-	}
 	if (graphic->stroke != NULL)
 		lsm_svg_view_push_stroke_attributes (view, graphic->stroke);
 	if (graphic->text != NULL)
@@ -184,13 +185,10 @@ lsm_svg_graphic_render (LsmSvgElement *self, LsmSvgView *view)
 		lsm_svg_view_pop_text_attributes (view);
 	if (graphic->stroke != NULL)
 		lsm_svg_view_pop_stroke_attributes (view);
-	if (graphic->fill != NULL) {
-		if (graphic->fill->clip_path.value != NULL)
-			lsm_svg_view_pop_clip (view);
+	if (graphic->fill != NULL)
 		lsm_svg_view_pop_fill_attributes (view);
-	}
-
-	lsm_svg_view_pop_opacity (view);
+	if (graphic->mask != NULL)
+		lsm_svg_view_pop_mask_attributes (view);
 
 	if (graphic->transform != NULL)
 		lsm_svg_view_pop_matrix (view);
@@ -275,7 +273,6 @@ lsm_svg_graphic_class_init (LsmSvgGraphicClass *s_graphic_class)
 
 	s_graphic_class->graphic_render = _graphic_render;
 	s_graphic_class->graphic_get_extents = _graphic_get_extents;
-	s_graphic_class->late_opacity_handling = FALSE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
@@ -285,9 +282,8 @@ lsm_svg_graphic_class_init (LsmSvgGraphicClass *s_graphic_class)
 					     offsetof (LsmSvgGraphic, style));
 	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "color",
 					     offsetof (LsmSvgGraphic, color));
-	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "opacity",
-					     offsetof (LsmSvgGraphic, opacity));
 
+	lsm_dom_attribute_map_add_mask_attribute_bag (s_element_class->attributes, offsetof (LsmSvgGraphic, mask));
 	lsm_dom_attribute_map_add_fill_attribute_bag (s_element_class->attributes, offsetof (LsmSvgGraphic, fill));
 	lsm_dom_attribute_map_add_stroke_attribute_bag (s_element_class->attributes, offsetof (LsmSvgGraphic, stroke));
 	lsm_dom_attribute_map_add_transform_attribute_bag (s_element_class->attributes,
diff --git a/src/lsmsvggraphic.h b/src/lsmsvggraphic.h
index 4127964..5750845 100644
--- a/src/lsmsvggraphic.h
+++ b/src/lsmsvggraphic.h
@@ -43,8 +43,8 @@ struct _LsmSvgGraphic {
 	LsmDomAttribute	style;
 
 	LsmSvgColorAttribute color;
-	LsmSvgDoubleAttribute opacity;
 
+	LsmSvgMaskAttributeBag *mask;
 	LsmSvgFillAttributeBag *fill;
 	LsmSvgStrokeAttributeBag *stroke;
 	LsmSvgTransformAttributeBag *transform;
@@ -57,8 +57,6 @@ struct _LsmSvgGraphicClass {
 
 	void 		(*graphic_render)	(LsmSvgElement *element, LsmSvgView *view);
 	void 		(*graphic_get_extents)	(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
-
-	gboolean	late_opacity_handling;
 };
 
 GType lsm_svg_graphic_get_type (void);
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index 3924c7d..a272bb3 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -107,7 +107,6 @@ lsm_svg_line_element_class_init (LsmSvgLineElementClass *s_rect_class)
 	s_element_class->update = lsm_svg_line_element_update;
 
 	s_graphic_class->graphic_render = lsm_svg_line_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgmaskelement.c b/src/lsmsvgmaskelement.c
new file mode 100644
index 0000000..d8a2a7a
--- /dev/null
+++ b/src/lsmsvgmaskelement.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmsvgmaskelement.h>
+#include <lsmsvgview.h>
+#include <lsmdebug.h>
+#include <stdio.h>
+
+static GObjectClass *parent_class;
+
+/* GdomNode implementation */
+
+static const char *
+_mask_element_get_node_name (LsmDomNode *node)
+{
+	return "mask";
+}
+
+/* LsmSvgElement implementation */
+
+static void
+_mask_element_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
+{
+	LsmSvgMaskElement *mask = LSM_SVG_MASK_ELEMENT (self);
+	LsmSvgPatternUnits units;
+	LsmSvgLength length;
+
+	units = LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX;
+	lsm_svg_pattern_units_attribute_parse (&mask->units, &units);
+
+	units = LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE;
+	lsm_svg_pattern_units_attribute_parse (&mask->content_units, &units);
+
+	length.value_unit = 0.0;
+	length.type = LSM_SVG_LENGTH_TYPE_PX;
+	lsm_svg_animated_length_attribute_parse (&mask->x, &length);
+
+	length.value_unit = 0.0;
+	length.type = LSM_SVG_LENGTH_TYPE_PX;
+	lsm_svg_animated_length_attribute_parse (&mask->y, &length);
+
+	length.value_unit = 0.0;
+	length.type = LSM_SVG_LENGTH_TYPE_PX;
+	lsm_svg_animated_length_attribute_parse (&mask->width, &length);
+
+	length.value_unit = 0.0;
+	length.type = LSM_SVG_LENGTH_TYPE_PX;
+	lsm_svg_animated_length_attribute_parse (&mask->height, &length);
+
+	LSM_SVG_ELEMENT_CLASS (parent_class)->update (self, parent_style);
+}
+
+static void
+_mask_element_render_paint (LsmSvgElement *self, LsmSvgView *view)
+{
+}
+
+/* LsmSvgMaskElement implementation */
+
+LsmDomNode *
+lsm_svg_mask_element_new (void)
+{
+	return g_object_new (LSM_TYPE_SVG_MASK_ELEMENT, NULL);
+}
+
+static void
+lsm_svg_mask_element_init (LsmSvgMaskElement *self)
+{
+	/* Hack - Force the creation of the attribute bags,
+	   making sure the properties will be inherited from the
+	   mask element ancestor, not the referencing one. */
+
+	lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "fill", NULL);
+	lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stroke", NULL);
+	lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "transform", NULL);
+	lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "font-family", NULL);
+	lsm_dom_element_set_attribute (LSM_DOM_ELEMENT (self), "stop-color", NULL);
+}
+
+/* LsmSvgMaskElement class */
+
+static void
+lsm_svg_mask_element_class_init (LsmSvgMaskElementClass *klass)
+{
+	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	d_node_class->get_node_name = _mask_element_get_node_name;
+
+	s_element_class->update = _mask_element_update;
+	s_element_class->render_paint = _mask_element_render_paint;
+	s_element_class->render = NULL;
+
+	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
+
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "x",
+					     offsetof (LsmSvgMaskElement, x));
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "y",
+					     offsetof (LsmSvgMaskElement, y));
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "width",
+					     offsetof (LsmSvgMaskElement, width));
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "height",
+					     offsetof (LsmSvgMaskElement, height));
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "maskUnits",
+					     offsetof (LsmSvgMaskElement, units));
+	lsm_dom_attribute_map_add_attribute (s_element_class->attributes, "maskContentUnits",
+					     offsetof (LsmSvgMaskElement, content_units));
+}
+
+G_DEFINE_TYPE (LsmSvgMaskElement, lsm_svg_mask_element, LSM_TYPE_SVG_GRAPHIC)
diff --git a/src/lsmsvgmaskelement.h b/src/lsmsvgmaskelement.h
new file mode 100644
index 0000000..c51338a
--- /dev/null
+++ b/src/lsmsvgmaskelement.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2009 Emmanuel Pacaud
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_SVG_MASK_ELEMENT_H
+#define LSM_SVG_MASK_ELEMENT_H
+
+#include <lsmsvg.h>
+#include <lsmsvggraphic.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_MASK_ELEMENT             (lsm_svg_mask_element_get_type ())
+#define LSM_SVG_MASK_ELEMENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_MASK_ELEMENT, LsmSvgMaskElement))
+#define LSM_SVG_MASK_ELEMENT_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_MASK_ELEMENT, LsmSvgMaskElementClass))
+#define LSM_IS_SVG_MASK_ELEMENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_MASK_ELEMENT))
+#define LSM_IS_SVG_MASK_ELEMENT_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_MASK_ELEMENT))
+#define LSM_SVG_MASK_ELEMENT_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_MASK_ELEMENT, LsmSvgMaskElementClass))
+
+typedef struct _LsmSvgMaskElementClass LsmSvgMaskElementClass;
+
+struct _LsmSvgMaskElement {
+	LsmSvgGraphic graphic;
+
+	LsmSvgAnimatedLengthAttribute	x;
+	LsmSvgAnimatedLengthAttribute	y;
+	LsmSvgAnimatedLengthAttribute	width;
+	LsmSvgAnimatedLengthAttribute	height;
+	LsmDomEnumAttribute 		units;
+	LsmDomEnumAttribute 		content_units;
+};
+
+struct _LsmSvgMaskElementClass {
+	LsmSvgGraphicClass  parent_class;
+};
+
+GType lsm_svg_mask_element_get_type (void);
+
+LsmDomNode * 	lsm_svg_mask_element_new 	(void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index 408f8cb..e7e55d1 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -82,7 +82,6 @@ lsm_svg_path_element_class_init (LsmSvgPathElementClass *s_rect_class)
 	d_node_class->get_node_name = lsm_svg_path_element_get_node_name;
 
 	s_graphic_class->graphic_render = lsm_svg_path_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgpolygonelement.c b/src/lsmsvgpolygonelement.c
index b30071c..a560e6f 100644
--- a/src/lsmsvgpolygonelement.c
+++ b/src/lsmsvgpolygonelement.c
@@ -71,7 +71,6 @@ lsm_svg_polygon_element_class_init (LsmSvgPolygonElementClass *s_rect_class)
 	d_node_class->get_node_name = lsm_svg_polygon_element_get_node_name;
 
 	s_graphic_class->graphic_render = lsm_svg_polygon_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgpolylineelement.c b/src/lsmsvgpolylineelement.c
index 37ff4f4..0facb9a 100644
--- a/src/lsmsvgpolylineelement.c
+++ b/src/lsmsvgpolylineelement.c
@@ -71,7 +71,6 @@ lsm_svg_polyline_element_class_init (LsmSvgPolylineElementClass *s_rect_class)
 	d_node_class->get_node_name = lsm_svg_polyline_element_get_node_name;
 
 	s_graphic_class->graphic_render = lsm_svg_polyline_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index 4e1388b..b039e9c 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -152,7 +152,6 @@ lsm_svg_rect_element_class_init (LsmSvgRectElementClass *s_rect_class)
 
 	s_graphic_class->graphic_render = lsm_svg_rect_element_graphic_render;
 	s_graphic_class->graphic_get_extents = lsm_svg_rect_element_graphic_get_extents;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index 845c552..f89c44e 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -124,7 +124,6 @@ lsm_svg_text_element_class_init (LsmSvgTextElementClass *s_rect_class)
 	s_element_class->update = lsm_svg_text_element_update;
 
 	s_graphic_class->graphic_render = lsm_svg_text_element_graphic_render;
-	s_graphic_class->late_opacity_handling = TRUE;
 
 	s_element_class->attributes = lsm_dom_attribute_map_duplicate (s_element_class->attributes);
 
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 03a6d66..59792d8 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -36,11 +36,6 @@
 
 static GObjectClass *parent_class;
 
-typedef struct {
-	double opacity;
-	gboolean late_opacity_handling;
-} LsmSvgViewOpacityData;
-
 struct _LsmSvgViewPatternData {
 	cairo_t *old_cairo;
 
@@ -861,14 +856,34 @@ lsm_svg_view_pop_matrix (LsmSvgView *view)
 }
 
 void
-lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_rule, const LsmExtents *extents)
+lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
+{
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (LSM_IS_SVG_ELEMENT (element));
+
+	view->element_stack = g_slist_prepend (view->element_stack, (void *) element);
+}
+
+void
+lsm_svg_view_pop_element (LsmSvgView *view)
+{
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (view->element_stack != NULL);
+
+	view->element_stack = g_slist_delete_link (view->element_stack, view->element_stack);
+}
+
+static void
+lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_rule)
 {
 	LsmDomElement *element;
+	LsmExtents extents;
 	char *uri;
 
 	g_return_if_fail (LSM_IS_SVG_VIEW (view));
 	g_return_if_fail (!view->is_clipping);
-	g_return_if_fail (extents != NULL);
+
+	lsm_svg_element_get_extents (view->element_stack->data, view, &extents);
 
 	uri = clip_path;
 
@@ -876,10 +891,10 @@ lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_r
 
 	cairo_save (view->dom_view.cairo);
 
-	view->clip_extents.x = extents->x1;
-	view->clip_extents.y = extents->y1;
-	view->clip_extents.width  = extents->x2 - extents->x1;
-	view->clip_extents.height = extents->y2 - extents->y1;
+	view->clip_extents.x = extents.x1;
+	view->clip_extents.y = extents.y1;
+	view->clip_extents.width  = extents.x2 - extents.x1;
+	view->clip_extents.height = extents.y2 - extents.y1;
 
 	if (strncmp (uri, "url(#", 5) ==0) {
 		char *end;
@@ -901,7 +916,7 @@ lsm_svg_view_push_clip (LsmSvgView *view, char *clip_path, LsmSvgFillRule clip_r
 	}
 }
 
-void
+static void
 lsm_svg_view_pop_clip (LsmSvgView *view)
 {
 	lsm_debug ("[LsmSvgView::pop_clip");
@@ -909,21 +924,71 @@ lsm_svg_view_pop_clip (LsmSvgView *view)
 	cairo_restore (view->dom_view.cairo);
 }
 
-gboolean
-lsm_svg_view_is_clipping (LsmSvgView *view)
+void
+lsm_svg_view_push_group_opacity (LsmSvgView *view)
+{
+	LsmSvgMaskAttributeBag *mask;
+
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (view->mask_stack != NULL);
+
+	mask = view->mask_stack->data;
+
+	if (mask->opacity.value < 1.0)
+		cairo_push_group (view->dom_view.cairo);
+}
+
+void
+lsm_svg_view_pop_group_opacity (LsmSvgView *view)
 {
-	g_return_val_if_fail (LSM_IS_SVG_VIEW (view), FALSE);
+	LsmSvgMaskAttributeBag *mask;
+
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (view->mask_stack != NULL);
 
-	return view->is_clipping;
+	mask = view->mask_stack->data;
+
+	if (mask->opacity.value < 1.0) {
+		cairo_pop_group_to_source (view->dom_view.cairo);
+		cairo_paint_with_alpha (view->dom_view.cairo, mask->opacity.value);
+	}
 }
 
 void
-lsm_svg_view_push_fill_attributes (LsmSvgView *view, LsmSvgFillAttributeBag *fill)
+lsm_svg_view_push_mask_attributes (LsmSvgView *view, const LsmSvgMaskAttributeBag *mask)
+{
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (mask != NULL);
+
+	view->mask_stack = g_slist_prepend (view->mask_stack, (void *) mask);
+
+	if (mask->clip_path.value != NULL)
+		lsm_svg_view_push_clip (view, mask->clip_path.value, mask->clip_rule.value);
+}
+
+void
+lsm_svg_view_pop_mask_attributes (LsmSvgView *view)
+{
+	LsmSvgMaskAttributeBag *mask;
+
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+	g_return_if_fail (view->mask_stack != NULL);
+
+	mask = view->mask_stack->data;
+
+	if (mask->clip_path.value != NULL)
+		lsm_svg_view_pop_clip (view);
+
+	view->mask_stack = g_slist_delete_link (view->mask_stack, view->mask_stack);
+}
+
+void
+lsm_svg_view_push_fill_attributes (LsmSvgView *view, const LsmSvgFillAttributeBag *fill)
 {
 	g_return_if_fail (LSM_IS_SVG_VIEW (view));
 	g_return_if_fail (fill != NULL);
 
-	view->fill_stack = g_slist_prepend (view->fill_stack, fill);
+	view->fill_stack = g_slist_prepend (view->fill_stack, (void *) fill);
 }
 
 void
@@ -936,12 +1001,12 @@ lsm_svg_view_pop_fill_attributes (LsmSvgView *view)
 }
 
 void
-lsm_svg_view_push_stroke_attributes (LsmSvgView *view, LsmSvgStrokeAttributeBag *stroke)
+lsm_svg_view_push_stroke_attributes (LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke)
 {
 	g_return_if_fail (LSM_IS_SVG_VIEW (view));
 	g_return_if_fail (stroke != NULL);
 
-	view->stroke_stack = g_slist_prepend (view->stroke_stack, stroke);
+	view->stroke_stack = g_slist_prepend (view->stroke_stack, (void *) stroke);
 }
 
 void
@@ -954,12 +1019,12 @@ lsm_svg_view_pop_stroke_attributes (LsmSvgView *view)
 }
 
 void
-lsm_svg_view_push_text_attributes (LsmSvgView *view, LsmSvgTextAttributeBag *text)
+lsm_svg_view_push_text_attributes (LsmSvgView *view, const LsmSvgTextAttributeBag *text)
 {
 	g_return_if_fail (LSM_IS_SVG_VIEW (view));
 	g_return_if_fail (text != NULL);
 
-	view->text_stack = g_slist_prepend (view->text_stack, text);
+	view->text_stack = g_slist_prepend (view->text_stack, (void *) text);
 }
 
 void
@@ -1078,33 +1143,35 @@ paint (LsmSvgView *view)
 {
 	LsmSvgFillAttributeBag *fill;
 	LsmSvgStrokeAttributeBag *stroke;
+	LsmSvgGraphic *graphic;
 	cairo_t *cairo;
 	gboolean use_group;
-	double global_opacity;
+	double group_opacity;
 
 	g_return_if_fail (view->fill_stack != NULL);
 	g_return_if_fail (view->stroke_stack != NULL);
+	g_return_if_fail (view->element_stack != NULL);
+
+	graphic = view->element_stack->data;
+
+	g_return_if_fail (LSM_IS_SVG_GRAPHIC (graphic));
 
 	cairo = view->dom_view.cairo;
 	fill = view->fill_stack->data;
 	stroke = view->stroke_stack->data;
 
-	if (view->opacity_stack != NULL) {
-		LsmSvgViewOpacityData *opacity_data;
+	if (view->mask_stack != NULL && view->mask_stack->data == graphic->mask) {
+		LsmSvgMaskAttributeBag *mask;
 
-		opacity_data = view->opacity_stack->data;
-		global_opacity = opacity_data->opacity;
+		mask = view->mask_stack->data;
+		group_opacity = mask->opacity.value;
 
 		use_group = fill->paint.paint.type != LSM_SVG_PAINT_TYPE_NONE &&
 			stroke->paint.paint.type != LSM_SVG_PAINT_TYPE_NONE &&
-			global_opacity < 1.0;
-
-		if (!opacity_data->late_opacity_handling)
-			g_warning ("[LsmSvgView::paint] Missing late_opacity_handling declaration in"
-				   " caller element");
+			group_opacity < 1.0;
 	} else {
 		use_group = FALSE;
-		global_opacity = 1.0;
+		group_opacity = 1.0;
 	}
 
 	/* FIXME Instead of push_group, restrict to the current path bounding box */
@@ -1112,14 +1179,14 @@ paint (LsmSvgView *view)
 		cairo_push_group (cairo);
 
 	if (_set_color (view, LSM_SVG_VIEW_PAINT_OPERATION_FILL,
-			&fill->paint.paint, fill->opacity.value * global_opacity)) {
+			&fill->paint.paint, fill->opacity.value * group_opacity)) {
 		cairo_set_fill_rule (cairo, fill->rule.value == LSM_SVG_FILL_RULE_EVEN_ODD ?
 				     CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
 		cairo_fill_preserve (cairo);
 	}
 
 	if (_set_color (view, LSM_SVG_VIEW_PAINT_OPERATION_STROKE,
-			&stroke->paint.paint, stroke->opacity.value * global_opacity)) {
+			&stroke->paint.paint, stroke->opacity.value * group_opacity)) {
 		double line_width;
 
 		switch (stroke->line_join.value) {
@@ -1180,7 +1247,7 @@ paint (LsmSvgView *view)
 
 	if (use_group) {
 		cairo_pop_group_to_source (cairo);
-		cairo_paint_with_alpha (cairo, global_opacity);
+		cairo_paint_with_alpha (cairo, group_opacity);
 	}
 }
 
@@ -1188,10 +1255,10 @@ static void
 process_path (LsmSvgView *view)
 {
 	if (view->is_clipping) {
-		LsmSvgFillAttributeBag *fill;
+		LsmSvgMaskAttributeBag *mask;
 
-		fill = view->fill_stack->data;
-		cairo_set_fill_rule (view->dom_view.cairo, fill->clip_rule.value);
+		mask = view->mask_stack->data;
+		cairo_set_fill_rule (view->dom_view.cairo, mask->clip_rule.value);
 	} else
 		paint (view);
 }
@@ -1395,41 +1462,6 @@ lsm_svg_view_show_pixbuf (LsmSvgView *view, GdkPixbuf *pixbuf)
 	cairo_paint (view->dom_view.cairo);
 }
 
-void
-lsm_svg_view_push_opacity (LsmSvgView *view, double opacity, gboolean late_opacity_handling)
-{
-	LsmSvgViewOpacityData *opacity_data;
-
-	g_return_if_fail (LSM_IS_SVG_VIEW (view));
-
-	opacity_data = g_new (LsmSvgViewOpacityData, 1);
-	opacity_data->opacity = opacity;
-	opacity_data->late_opacity_handling = late_opacity_handling;
-
-	if (opacity < 1.0 && !late_opacity_handling)
-		cairo_push_group (view->dom_view.cairo);
-
-	view->opacity_stack = g_slist_prepend (view->opacity_stack, opacity_data);
-}
-
-void
-lsm_svg_view_pop_opacity (LsmSvgView *view)
-{
-	LsmSvgViewOpacityData *opacity_data;
-
-	g_return_if_fail (LSM_IS_SVG_VIEW (view));
-	g_return_if_fail (view->opacity_stack != NULL);
-
-	opacity_data = view->opacity_stack->data;
-
-	if (opacity_data->opacity < 1.0 && !opacity_data->late_opacity_handling) {
-		cairo_pop_group_to_source (view->dom_view.cairo);
-		cairo_paint_with_alpha (view->dom_view.cairo, opacity_data->opacity);
-	}
-
-	view->opacity_stack = g_slist_delete_link (view->opacity_stack, view->opacity_stack);
-}
-
 static void
 lsm_svg_view_measure (LsmDomView *view, double *width, double *height)
 {
@@ -1458,10 +1490,11 @@ lsm_svg_view_render (LsmDomView *view)
 
 	lsm_svg_svg_element_update (svg_element);
 
+	svg_view->element_stack = NULL;
 	svg_view->viewbox_stack = NULL;
+	svg_view->mask_stack = NULL;
 	svg_view->fill_stack = NULL;
 	svg_view->stroke_stack = NULL;
-	svg_view->opacity_stack = NULL;
 	svg_view->text_stack = NULL;
 	svg_view->matrix_stack = NULL;
 
@@ -1484,26 +1517,31 @@ lsm_svg_view_render (LsmDomView *view)
 		g_slist_free (svg_view->viewbox_stack);
 		svg_view->viewbox_stack = NULL;
 	}
-	if (svg_view->opacity_stack != NULL) {
-		g_warning ("[LsmSvgView::render] Dangling opacity data in stack");
-		g_slist_free (svg_view->opacity_stack);
-		svg_view->opacity_stack = NULL;
-	}
 	if (svg_view->fill_stack != NULL) {
-		g_warning ("[LsmSvgView::render] Dangling fill attribute in stack");
+		g_warning ("[LsmSvgView::render] Dangling fill attributes in stack");
 		g_slist_free (svg_view->fill_stack);
 		svg_view->fill_stack = NULL;
 	}
 	if (svg_view->stroke_stack != NULL) {
-		g_warning ("[LsmSvgView::render] Dangling stroke attribute in stack");
+		g_warning ("[LsmSvgView::render] Dangling stroke attributes in stack");
 		g_slist_free (svg_view->stroke_stack);
 		svg_view->stroke_stack = NULL;
 	}
+	if (svg_view->mask_stack != NULL) {
+		g_warning ("[LsmSvgView::render] Dangling mask attributes in stack");
+		g_slist_free (svg_view->mask_stack);
+		svg_view->mask_stack = NULL;
+	}
 	if (svg_view->text_stack != NULL) {
 		g_warning ("[LsmSvgView::render] Dangling text attribute in stack");
 		g_slist_free (svg_view->text_stack);
 		svg_view->text_stack = NULL;
 	}
+	if (svg_view->element_stack != NULL) {
+		g_warning ("[LsmSvgView::render] Dangling element in stack");
+		g_slist_free (svg_view->element_stack);
+		svg_view->element_stack = NULL;
+	}
 }
 
 LsmSvgView *
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index 72a0b3a..63f6925 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -46,10 +46,11 @@ struct _LsmSvgView {
 
 	double resolution_ppi;
 
+	GSList *element_stack;
 	GSList *viewbox_stack;
+	GSList *mask_stack;
 	GSList *fill_stack;
 	GSList *stroke_stack;
-	GSList *opacity_stack;
 	GSList *text_stack;
 	GSList *matrix_stack;
 
@@ -98,15 +99,17 @@ void 		lsm_svg_view_push_viewport 		(LsmSvgView *view, const LsmBox *viewport,
 void 		lsm_svg_view_pop_viewport 		(LsmSvgView *view);
 void 		lsm_svg_view_push_matrix		(LsmSvgView *view, LsmSvgMatrix *matrix);
 void 		lsm_svg_view_pop_matrix			(LsmSvgView *view);
-void 		lsm_svg_view_push_clip 			(LsmSvgView *view, char *clip_path,
-							 LsmSvgFillRule clip_rule, const LsmExtents *extents);
-void 		lsm_svg_view_pop_clip 			(LsmSvgView *view);
-gboolean 	lsm_svg_view_is_clipping 		(LsmSvgView *view);
-void 		lsm_svg_view_push_fill_attributes 	(LsmSvgView *view, LsmSvgFillAttributeBag *fill);
+
+void		lsm_svg_view_push_element		(LsmSvgView *view, const LsmSvgElement *element);
+void		lsm_svg_view_pop_element		(LsmSvgView *view);
+
+void		lsm_svg_view_push_mask_attributes	(LsmSvgView *view, const LsmSvgMaskAttributeBag *mask);
+void		lsm_svg_view_pop_mask_attributes	(LsmSvgView *view);
+void 		lsm_svg_view_push_fill_attributes 	(LsmSvgView *view, const LsmSvgFillAttributeBag *fill);
 void 		lsm_svg_view_pop_fill_attributes 	(LsmSvgView *view);
-void 		lsm_svg_view_push_stroke_attributes 	(LsmSvgView *view, LsmSvgStrokeAttributeBag *stroke);
+void 		lsm_svg_view_push_stroke_attributes 	(LsmSvgView *view, const LsmSvgStrokeAttributeBag *stroke);
 void 		lsm_svg_view_pop_stroke_attributes 	(LsmSvgView *view);
-void 		lsm_svg_view_push_text_attributes 	(LsmSvgView *view, LsmSvgTextAttributeBag *text);
+void 		lsm_svg_view_push_text_attributes 	(LsmSvgView *view, const LsmSvgTextAttributeBag *text);
 void 		lsm_svg_view_pop_text_attributes 	(LsmSvgView *view);
 
 void 		lsm_svg_view_show_rectangle 	(LsmSvgView *view, double x, double y,
@@ -121,8 +124,8 @@ void 		lsm_svg_view_show_polygon	(LsmSvgView *view, const char *points);
 void 		lsm_svg_view_show_text 		(LsmSvgView *view, char const *text, double x, double y);
 void		lsm_svg_view_show_pixbuf	(LsmSvgView *view, GdkPixbuf *pixbuf);
 
-void 		lsm_svg_view_push_opacity 	(LsmSvgView *view, double opacity, gboolean late_opacity_handling);
-void 		lsm_svg_view_pop_opacity 	(LsmSvgView *view);
+void 		lsm_svg_view_push_group_opacity (LsmSvgView *view);
+void 		lsm_svg_view_pop_group_opacity 	(LsmSvgView *view);
 
 G_END_DECLS
 



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