[lasem] svg_filter: begin the work on really applying filters.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg_filter: begin the work on really applying filters.
- Date: Sun, 29 Aug 2010 07:56:01 +0000 (UTC)
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]