[lasem] svg_filter: add feMerge and feMergeNode support.



commit 066fbcac8cb906eaf7e85babb7d05b901c10a7e0
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sun Oct 14 22:29:45 2012 +0200

    svg_filter: add feMerge and feMergeNode support.

 docs/reference/lasem/Makefile.am |    4 +-
 src/Makefile.am                  |    8 ++-
 src/lsmcairo.c                   |   18 +++++++
 src/lsmcairo.h                   |    1 +
 src/lsmsvgdocument.c             |    6 ++
 src/lsmsvgfiltermerge.c          |   98 ++++++++++++++++++++++++++++++++++++++
 src/lsmsvgfiltermerge.h          |   55 +++++++++++++++++++++
 src/lsmsvgfiltermergenode.c      |   88 ++++++++++++++++++++++++++++++++++
 src/lsmsvgfiltermergenode.h      |   57 ++++++++++++++++++++++
 src/lsmsvgtypes.h                |    2 +
 src/lsmsvgview.c                 |   23 +++++++++
 src/lsmsvgview.h                 |    1 +
 12 files changed, 358 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/lasem/Makefile.am b/docs/reference/lasem/Makefile.am
index 8ee57c9..582f8c0 100644
--- a/docs/reference/lasem/Makefile.am
+++ b/docs/reference/lasem/Makefile.am
@@ -151,7 +151,9 @@ IGNORE_HFILES=\
 	lsmsvgfiltercomposite.h			\
 	lsmsvgfilterflood.h			\
 	lsmsvgfiltergaussianblur.h		\
-	lsmsvgfilteroffset.h
+	lsmsvgfilteroffset.h			\
+	lsmsvgfiltermerge.h			\
+	lsmsvgfiltermergenode.h
 
 # Images to copy into HTML directory.
 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
diff --git a/src/Makefile.am b/src/Makefile.am
index 835299b..4324367 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -130,7 +130,9 @@ LASEM_SVG_SRCS =				\
 	lsmsvgfiltercomposite.c			\
 	lsmsvgfilterflood.c			\
 	lsmsvgfiltergaussianblur.c		\
-	lsmsvgfilteroffset.c
+	lsmsvgfilteroffset.c			\
+	lsmsvgfiltermerge.c			\
+	lsmsvgfiltermergenode.c
 
 LASEM_DOM_HDRS = 				\
 	lsm.h					\
@@ -239,7 +241,9 @@ LASEM_SVG_HDRS =				\
 	lsmsvgfiltercomposite.h			\
 	lsmsvgfilterflood.h			\
 	lsmsvgfiltergaussianblur.h		\
-	lsmsvgfilteroffset.h
+	lsmsvgfilteroffset.h			\
+	lsmsvgfiltermerge.h			\
+	lsmsvgfiltermergenode.h
 
 liblasem_ LASEM_API_VERSION@_ladir = $(includedir)/lasem- LASEM_API_VERSION@
 
diff --git a/src/lsmcairo.c b/src/lsmcairo.c
index 1a5e28b..bca1fc7 100644
--- a/src/lsmcairo.c
+++ b/src/lsmcairo.c
@@ -383,6 +383,24 @@ lsm_filter_surface_offset (LsmFilterSurface *input,
 }
 
 void
+lsm_filter_surface_merge (LsmFilterSurface *input,
+			  LsmFilterSurface *output)
+{
+	cairo_t *cairo;
+
+	g_return_if_fail (input != NULL);
+	g_return_if_fail (output != NULL);
+
+	cairo_surface_flush (input->surface);
+
+	cairo = cairo_create (output->surface);
+	cairo_set_source_surface (cairo, input->surface, 0, 0);
+	cairo_paint (cairo);
+
+	cairo_destroy (cairo);
+}
+
+void
 lsm_filter_surface_alpha (LsmFilterSurface *input, LsmFilterSurface *output)
 {
 	cairo_t *cairo;
diff --git a/src/lsmcairo.h b/src/lsmcairo.h
index e911409..7268e69 100644
--- a/src/lsmcairo.h
+++ b/src/lsmcairo.h
@@ -60,6 +60,7 @@ void 			lsm_filter_surface_fast_blur 		(LsmFilterSurface *input,
 								 double sx, double sy);
 void 			lsm_filter_surface_flood 		(LsmFilterSurface *surface, guint32 color, double opacity);
 void 			lsm_filter_surface_offset 		(LsmFilterSurface *input, LsmFilterSurface *output, int dx, int dy);
+void 			lsm_filter_surface_merge 		(LsmFilterSurface *input, LsmFilterSurface *output);
 
 void 			lsm_cairo_set_source_pixbuf 		(cairo_t         *cr,
 								 const GdkPixbuf *pixbuf,
diff --git a/src/lsmsvgdocument.c b/src/lsmsvgdocument.c
index f81f559..64fdff8 100644
--- a/src/lsmsvgdocument.c
+++ b/src/lsmsvgdocument.c
@@ -51,6 +51,8 @@
 #include <lsmsvgfilterflood.h>
 #include <lsmsvgfiltergaussianblur.h>
 #include <lsmsvgfilteroffset.h>
+#include <lsmsvgfiltermerge.h>
+#include <lsmsvgfiltermergenode.h>
 #include <lsmsvgview.h>
 #include <string.h>
 
@@ -146,6 +148,10 @@ _create_element (LsmDomDocument *document, const char *tag_name)
 		node = lsm_svg_filter_flood_new ();
 	else if (strcmp (tag_name, "feGaussianBlur") == 0)
 		node = lsm_svg_filter_gaussian_blur_new ();
+	else if (strcmp (tag_name, "feMerge") == 0)
+		node = lsm_svg_filter_merge_new ();
+	else if (strcmp (tag_name, "feMergeNode") == 0)
+		node = lsm_svg_filter_merge_node_new ();
 	else if (strcmp (tag_name, "feOffset") == 0)
 		node = lsm_svg_filter_offset_new ();
 
diff --git a/src/lsmsvgfiltermerge.c b/src/lsmsvgfiltermerge.c
new file mode 100644
index 0000000..76c39a9
--- /dev/null
+++ b/src/lsmsvgfiltermerge.c
@@ -0,0 +1,98 @@
+/* Lasem
+ * 
+ * Copyright  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>
+ */
+
+#include <lsmsvgfiltermerge.h>
+#include <lsmsvgfiltermergenode.h>
+#include <lsmsvgview.h>
+
+static GObjectClass *parent_class;
+
+/* GdomNode implementation */
+
+static const char *
+lsm_svg_filter_merge_get_node_name (LsmDomNode *node)
+{
+	return "feMerge";
+}
+
+static gboolean
+lsm_svg_filter_merge_can_append_child (LsmDomNode *self, LsmDomNode *child)
+{
+	return LSM_IS_SVG_FILTER_MERGE_NODE (child);
+}
+
+/* LsmSvgElement implementation */
+
+static void
+lsm_svg_filter_merge_apply  (LsmSvgFilterPrimitive *self, LsmSvgView *view,
+			     const char *input, const char *output,
+			     double x, double y, double w, double h)
+{
+	LsmDomNode *iter;
+
+	for (iter = LSM_DOM_NODE (self)->first_child; iter != NULL; iter = iter->next_sibling)
+		lsm_svg_filter_primitive_apply (LSM_SVG_FILTER_PRIMITIVE (iter), view);
+}
+
+/* LsmSvgFilterMerge implementation */
+
+LsmDomNode *
+lsm_svg_filter_merge_new (void)
+{
+	return g_object_new (LSM_TYPE_SVG_FILTER_MERGE, NULL);
+}
+
+static void
+lsm_svg_filter_merge_init (LsmSvgFilterMerge *self)
+{
+}
+
+static void
+lsm_svg_filter_merge_finalize (GObject *object)
+{
+	parent_class->finalize (object);
+}
+
+/* LsmSvgFilterMerge class */
+
+static void
+lsm_svg_filter_merge_class_init (LsmSvgFilterMergeClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
+	LsmSvgFilterPrimitiveClass *f_primitive_class = LSM_SVG_FILTER_PRIMITIVE_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = lsm_svg_filter_merge_finalize;
+
+	d_node_class->get_node_name = lsm_svg_filter_merge_get_node_name;
+	d_node_class->can_append_child = lsm_svg_filter_merge_can_append_child;
+
+	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+	f_primitive_class->apply = lsm_svg_filter_merge_apply;
+}
+
+G_DEFINE_TYPE (LsmSvgFilterMerge, lsm_svg_filter_merge, LSM_TYPE_SVG_FILTER_PRIMITIVE)
diff --git a/src/lsmsvgfiltermerge.h b/src/lsmsvgfiltermerge.h
new file mode 100644
index 0000000..0933a8d
--- /dev/null
+++ b/src/lsmsvgfiltermerge.h
@@ -0,0 +1,55 @@
+/* Lasem
+ *
+ * Copyright  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_FILTER_MERGE_H
+#define LSM_SVG_FILTER_MERGE_H
+
+#include <lsmsvgtypes.h>
+#include <lsmsvgfilterprimitive.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_FILTER_MERGE             (lsm_svg_filter_merge_get_type ())
+#define LSM_SVG_FILTER_MERGE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_FILTER_MERGE, LsmSvgFilterMerge))
+#define LSM_SVG_FILTER_MERGE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_FILTER_MERGE, LsmSvgFilterMergeClass))
+#define LSM_IS_SVG_FILTER_MERGE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_FILTER_MERGE))
+#define LSM_IS_SVG_FILTER_MERGE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_FILTER_MERGE))
+#define LSM_SVG_FILTER_MERGE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_FILTER_MERGE, LsmSvgFilterMergeClass))
+
+typedef struct _LsmSvgFilterMergeClass LsmSvgFilterMergeClass;
+
+struct _LsmSvgFilterMerge {
+	LsmSvgFilterPrimitive base;
+};
+
+struct _LsmSvgFilterMergeClass {
+	LsmSvgFilterPrimitiveClass  element_class;
+};
+
+GType lsm_svg_filter_merge_get_type (void);
+
+LsmDomNode * 	lsm_svg_filter_merge_new 		(void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgfiltermergenode.c b/src/lsmsvgfiltermergenode.c
new file mode 100644
index 0000000..da11e51
--- /dev/null
+++ b/src/lsmsvgfiltermergenode.c
@@ -0,0 +1,88 @@
+/* Lasem
+ * 
+ * Copyright  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>
+ */
+
+#include <lsmsvgfiltermergenode.h>
+#include <lsmsvgview.h>
+
+static GObjectClass *parent_class;
+
+/* GdomNode implementation */
+
+static const char *
+lsm_svg_filter_merge_node_get_node_name (LsmDomNode *node)
+{
+	return "feMergeNode";
+}
+
+/* LsmSvgElement implementation */
+
+static void
+lsm_svg_filter_merge_node_apply  (LsmSvgFilterPrimitive *self, LsmSvgView *view,
+				  const char *input, const char *output,
+				  double x, double y, double w, double h)
+{
+	/* FIXME We probably want to retrieve output name from parent feMerge element */
+	lsm_svg_view_apply_merge (view, input, "MergeSurface");
+}
+
+/* LsmSvgFilterMergeNode implementation */
+
+LsmDomNode *
+lsm_svg_filter_merge_node_new (void)
+{
+	return g_object_new (LSM_TYPE_SVG_FILTER_MERGE_NODE, NULL);
+}
+
+static void
+lsm_svg_filter_merge_node_init (LsmSvgFilterMergeNode *self)
+{
+}
+
+static void
+lsm_svg_filter_merge_node_finalize (GObject *object)
+{
+	parent_class->finalize (object);
+}
+
+/* LsmSvgFilterMergeNode class */
+
+static void
+lsm_svg_filter_merge_node_class_init (LsmSvgFilterMergeNodeClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
+	LsmSvgFilterPrimitiveClass *f_primitive_class = LSM_SVG_FILTER_PRIMITIVE_CLASS (klass);
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = lsm_svg_filter_merge_node_finalize;
+
+	d_node_class->get_node_name = lsm_svg_filter_merge_node_get_node_name;
+
+	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+	f_primitive_class->apply = lsm_svg_filter_merge_node_apply;
+}
+
+G_DEFINE_TYPE (LsmSvgFilterMergeNode, lsm_svg_filter_merge_node, LSM_TYPE_SVG_FILTER_PRIMITIVE)
diff --git a/src/lsmsvgfiltermergenode.h b/src/lsmsvgfiltermergenode.h
new file mode 100644
index 0000000..03d0ed0
--- /dev/null
+++ b/src/lsmsvgfiltermergenode.h
@@ -0,0 +1,57 @@
+/* Lasem
+ *
+ * Copyright  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_FILTER_MERGE_NODE_H
+#define LSM_SVG_FILTER_MERGE_NODE_H
+
+#include <lsmsvgtypes.h>
+#include <lsmsvgfilterprimitive.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_FILTER_MERGE_NODE             (lsm_svg_filter_merge_node_get_type ())
+#define LSM_SVG_FILTER_MERGE_NODE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_FILTER_MERGE_NODE, LsmSvgFilterMergeNode))
+#define LSM_SVG_FILTER_MERGE_NODE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_FILTER_MERGE_NODE, LsmSvgFilterMergeNodeClass))
+#define LSM_IS_SVG_FILTER_MERGE_NODE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_FILTER_MERGE_NODE))
+#define LSM_IS_SVG_FILTER_MERGE_NODE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_FILTER_MERGE_NODE))
+#define LSM_SVG_FILTER_MERGE_NODE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_FILTER_MERGE_NODE, LsmSvgFilterMergeNodeClass))
+
+typedef struct _LsmSvgFilterMergeNodeClass LsmSvgFilterMergeNodeClass;
+
+struct _LsmSvgFilterMergeNode {
+	LsmSvgFilterPrimitive base;
+
+	LsmSvgOneOrTwoDoubleAttribute std_deviation;
+};
+
+struct _LsmSvgFilterMergeNodeClass {
+	LsmSvgFilterPrimitiveClass  element_class;
+};
+
+GType lsm_svg_filter_merge_node_get_type (void);
+
+LsmDomNode * 	lsm_svg_filter_merge_node_new 		(void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgtypes.h b/src/lsmsvgtypes.h
index 30dba1c..c8a7e63 100644
--- a/src/lsmsvgtypes.h
+++ b/src/lsmsvgtypes.h
@@ -62,6 +62,8 @@ typedef struct _LsmSvgFilterComposite LsmSvgFilterComposite;
 typedef struct _LsmSvgFilterFlood LsmSvgFilterFlood;
 typedef struct _LsmSvgFilterGaussianBlur LsmSvgFilterGaussianBlur;
 typedef struct _LsmSvgFilterOffset LsmSvgFilterOffset;
+typedef struct _LsmSvgFilterMerge LsmSvgFilterMerge;
+typedef struct _LsmSvgFilterMergeNode LsmSvgFilterMergeNode;
 
 typedef struct _LsmSvgView LsmSvgView;
 typedef struct _LsmSvgStyle LsmSvgStyle;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 6e61f72..2421074 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -2194,6 +2194,29 @@ lsm_svg_view_apply_offset (LsmSvgView *view, const char *input, const char *outp
 }
 
 void
+lsm_svg_view_apply_merge (LsmSvgView *view, const char *input, const char *output)
+{
+	LsmFilterSurface *input_surface;
+	LsmFilterSurface *output_surface;
+
+	g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+	input_surface = _get_filter_surface (view, input);
+
+	if (input_surface == NULL) {
+		lsm_debug_render ("[SvgView::apply_offset] Input '%s' not found", input);
+		return;
+	}
+
+	output_surface = _get_filter_surface (view, output);
+	if (output_surface == NULL)
+		output_surface = _create_filter_surface (view, output, input_surface);
+
+	if (output_surface != NULL)
+		lsm_filter_surface_merge (input_surface, output_surface);
+}
+
+void
 lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
 {
 	g_return_if_fail (LSM_IS_SVG_VIEW (view));
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index 00d150f..d48f501 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -162,6 +162,7 @@ void		lsm_svg_view_apply_gaussian_blur 	(LsmSvgView *view, const char *input, co
 							 double x, double y, double w, double h,
 							 double std_x, double std_y);
 void 		lsm_svg_view_apply_offset 		(LsmSvgView *view, const char *input, const char *output, double dx, double dy);
+void 		lsm_svg_view_apply_merge 		(LsmSvgView *view, const char *input, const char *output);
 
 G_END_DECLS
 



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