[lasem] svg_filter: begin the work on really applying filters.



commit e9025ebd49459ac1de06e3839d70da6e3a6f5a91
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sun Aug 29 09:52:03 2010 +0200

    svg_filter: begin the work on really applying filters.

 src/lsmsvgfilterelement.c      |   57 ++++++++++++++++++++++++++++++++++++++++
 src/lsmsvgfiltergaussianblur.c |   25 ++++++++++++++---
 src/lsmsvgfilterprimitive.c    |   20 +++++++++++++-
 src/lsmsvgfilterprimitive.h    |    8 +++++-
 4 files changed, 103 insertions(+), 7 deletions(-)
---
diff --git a/src/lsmsvgfilterelement.c b/src/lsmsvgfilterelement.c
index b0d214f..73f3c96 100644
--- a/src/lsmsvgfilterelement.c
+++ b/src/lsmsvgfilterelement.c
@@ -21,6 +21,7 @@
  */
 
 #include <lsmsvgfilterelement.h>
+#include <lsmsvgfilterprimitive.h>
 #include <lsmsvgview.h>
 #include <lsmdebug.h>
 
@@ -47,6 +48,10 @@ static void
 lsm_svg_filter_element_render (LsmSvgElement *self, LsmSvgView *view)
 {
 	LsmSvgFilterElement *filter = LSM_SVG_FILTER_ELEMENT (self);
+	LsmDomNode *node;
+	LsmBox viewport;
+	const LsmBox *filter_extents;
+	gboolean is_object_bounding_box;
 
 	if (!filter->enable_rendering) {
 		lsm_debug ("render", "[LsmSvgFilterElement::render] Direct rendering not allowed");
@@ -54,6 +59,58 @@ lsm_svg_filter_element_render (LsmSvgElement *self, LsmSvgView *view)
 	} else {
 		filter->enable_rendering = FALSE;
 	}
+
+	filter_extents = lsm_svg_view_get_pattern_extents (view);
+
+	is_object_bounding_box = (filter->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+	if (is_object_bounding_box) {
+		LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
+
+		lsm_svg_view_push_viewbox (view, &viewbox);
+	}
+
+	viewport.x      = lsm_svg_view_normalize_length (view, &filter->x.length,
+							 LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	viewport.y      = lsm_svg_view_normalize_length (view, &filter->y.length,
+							 LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	viewport.width  = lsm_svg_view_normalize_length (view, &filter->width.length,
+							 LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	viewport.height = lsm_svg_view_normalize_length (view, &filter->height.length,
+							 LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+	if (is_object_bounding_box) {
+		lsm_svg_view_pop_viewbox (view);
+
+		viewport.x = viewport.x * filter_extents->width + filter_extents->x;
+		viewport.y = viewport.y * filter_extents->height + filter_extents->y;
+		viewport.width *= filter_extents->width;
+		viewport.height *= filter_extents->height;
+	}
+
+	if (viewport.width <= 0.0 || viewport.height <= 0.0) {
+		lsm_debug ("render", "[LsmSvgFilterElement::render] Invalid filter area w = %g, h = %g",
+			   viewport.width, viewport.height);
+		return;
+	}
+
+	lsm_debug ("render", "[LsmFilterElement::render] Render filter x = %g, y = %g, w = %g, h = %g",
+		   viewport.x, viewport.y, viewport.width, viewport.height);
+
+	is_object_bounding_box = (filter->primitive_units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
+
+	if (is_object_bounding_box) {
+		LsmBox viewbox = {.x = 0.0, .y = .0, .width = 1.0, .height = 1.0};
+
+		lsm_svg_view_push_viewbox (view, &viewbox);
+	}
+
+	for (node = LSM_DOM_NODE (filter)->first_child; node != NULL; node = node->next_sibling)
+		if (LSM_IS_SVG_FILTER_PRIMITIVE (node))
+		    lsm_svg_filter_primitive_apply (LSM_SVG_FILTER_PRIMITIVE (node), view);
+
+	if (is_object_bounding_box)
+		lsm_svg_view_pop_viewbox (view);
 }
 
 static void
diff --git a/src/lsmsvgfiltergaussianblur.c b/src/lsmsvgfiltergaussianblur.c
index d3ceec6..d3e9023 100644
--- a/src/lsmsvgfiltergaussianblur.c
+++ b/src/lsmsvgfiltergaussianblur.c
@@ -35,6 +35,18 @@ lsm_svg_filter_gaussian_blur_get_node_name (LsmDomNode *node)
 
 /* LsmSvgElement implementation */
 
+static void
+lsm_svg_filter_gaussian_blur_apply  (LsmSvgFilterPrimitive *self, LsmSvgView *view,
+				     const char *input, const char *output,
+				     double x, double y, double w, double h)
+{
+	LsmSvgFilterGaussianBlur *blur = LSM_SVG_FILTER_GAUSSIAN_BLUR (self);
+
+	lsm_svg_view_apply_gaussian_blur (view, input, output, x, y, w, h,
+					  blur->std_deviation.value.a,
+					  blur->std_deviation.value.b);
+}
+
 /* LsmSvgFilterGaussianBlur implementation */
 
 static const LsmSvgOneOrTwoDouble std_deviation_default =  {.a = 0.0, .b = 0.0};
@@ -69,13 +81,14 @@ static const LsmAttributeInfos lsm_svg_filter_gaussian_blur_attribute_infos[] =
 };
 
 static void
-lsm_svg_filter_gaussian_blur_class_init (LsmSvgFilterGaussianBlurClass *s_rect_class)
+lsm_svg_filter_gaussian_blur_class_init (LsmSvgFilterGaussianBlurClass *f_blur_class)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (s_rect_class);
-	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (s_rect_class);
-	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (s_rect_class);
+	GObjectClass *object_class = G_OBJECT_CLASS (f_blur_class);
+	LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (f_blur_class);
+	LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (f_blur_class);
+	LsmSvgFilterPrimitiveClass *f_primitive_class = LSM_SVG_FILTER_PRIMITIVE_CLASS (f_blur_class);
 
-	parent_class = g_type_class_peek_parent (s_rect_class);
+	parent_class = g_type_class_peek_parent (f_blur_class);
 
 	object_class->finalize = lsm_svg_filter_gaussian_blur_finalize;
 
@@ -86,6 +99,8 @@ lsm_svg_filter_gaussian_blur_class_init (LsmSvgFilterGaussianBlurClass *s_rect_c
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_filter_gaussian_blur_attribute_infos),
 					      lsm_svg_filter_gaussian_blur_attribute_infos);
+
+	f_primitive_class->apply = lsm_svg_filter_gaussian_blur_apply;
 }
 
 G_DEFINE_TYPE (LsmSvgFilterGaussianBlur, lsm_svg_filter_gaussian_blur, LSM_TYPE_SVG_FILTER_PRIMITIVE)
diff --git a/src/lsmsvgfilterprimitive.c b/src/lsmsvgfilterprimitive.c
index 30160a7..5028dfd 100644
--- a/src/lsmsvgfilterprimitive.c
+++ b/src/lsmsvgfilterprimitive.c
@@ -37,6 +37,25 @@ lsm_svg_filter_primitive_can_append_child (LsmDomNode *self, LsmDomNode *child)
 
 /* LsmSvgFilterPrimitive implementation */
 
+void
+lsm_svg_filter_primitive_apply  (LsmSvgFilterPrimitive *self, LsmSvgView *view)
+{
+	LsmSvgFilterPrimitiveClass *primitive_class;
+	double x, y, w, h;
+
+	g_return_if_fail (LSM_IS_SVG_FILTER_PRIMITIVE (self));
+
+	primitive_class = LSM_SVG_FILTER_PRIMITIVE_GET_CLASS (self);
+
+	x = lsm_svg_view_normalize_length (view, &self->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	y = lsm_svg_view_normalize_length (view, &self->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+	w = lsm_svg_view_normalize_length (view, &self->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
+	h = lsm_svg_view_normalize_length (view, &self->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
+
+	if (primitive_class->apply != NULL)
+		primitive_class->apply (self, view, NULL, NULL, x, y, w, h);
+}
+
 static const LsmSvgLength x_y_default = 	 { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
 static const LsmSvgLength width_height_default = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
 
@@ -98,7 +117,6 @@ lsm_svg_filter_primitive_class_init (LsmSvgFilterPrimitiveClass *s_rect_class)
 	d_node_class->can_append_child = lsm_svg_filter_primitive_can_append_child;
 
 	s_element_class->category = LSM_SVG_ELEMENT_CATEGORY_FILTER_PRIMITIVE;
-
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
diff --git a/src/lsmsvgfilterprimitive.h b/src/lsmsvgfilterprimitive.h
index 61351f1..2ee8f93 100644
--- a/src/lsmsvgfilterprimitive.h
+++ b/src/lsmsvgfilterprimitive.h
@@ -48,9 +48,15 @@ struct _LsmSvgFilterPrimitive {
 
 struct _LsmSvgFilterPrimitiveClass {
 	LsmSvgElementClass  element_class;
+
+	void (*apply)		(LsmSvgFilterPrimitive *self, LsmSvgView *view,
+				 const char *input, const char *output,
+				 double x, double y, double w, double h);
 };
 
-GType lsm_svg_filter_primitive_get_type (void);
+GType 	lsm_svg_filter_primitive_get_type 	(void);
+
+void 	lsm_svg_filter_primitive_apply 		(LsmSvgFilterPrimitive *self, LsmSvgView *view);
 
 G_END_DECLS
 



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