Index: src/display/nr-arena-item.cpp
===================================================================
--- src/display/nr-arena-item.cpp	(revision 12088)
+++ src/display/nr-arena-item.cpp	(working copy)
@@ -23,6 +23,11 @@
 //#include "nr-arena-group.h"
 #include "gc-core.h"
 
+#include "nr-filter.h"
+/* prefs-utils used for deciding, whether to run filtering test or not */
+#include "prefs-utils.h"
+#include "nr-arena-shape.h"
+
 namespace GC = Inkscape::GC;
 
 static void nr_arena_item_class_init (NRArenaItemClass *klass);
@@ -537,7 +542,7 @@
 #endif
   } else {
     /* Determine, whether we need temporary buffer */
-    if (item->clip || item->mask || ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE)) {
+    if (item->clip || item->mask || ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE) || prefs_get_int_attribute("options.filtertest", "value", 0) != 0) {
       NRPixBlock ipb, mpb;
 
       /* Setup and render item buffer */
@@ -553,6 +558,13 @@
       }
       ipb.empty = FALSE;
 
+      /* Run filtering test, if a hidden option is set */
+      if(prefs_get_int_attribute("options.filtertest", "value", 0) != 0
+	 && NR_IS_ARENA_SHAPE(item)) {
+	NR::Filter f;
+	f.render(NULL, &ipb);
+      }
+
       if (item->clip || item->mask) {
         /* Setup mask pixblock */
         nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
Index: src/display/nr-filter.h
===================================================================
--- src/display/nr-filter.h	(revision 0)
+++ src/display/nr-filter.h	(revision 0)
@@ -0,0 +1,56 @@
+#ifndef __NR_FILTER_H__
+#define __NR_FILTER_H__
+
+/*
+ * SVG filters rendering
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "display/nr-arena-item.h"
+#include "display/nr-filter-primitive.h"
+#include "libnr/nr-pixblock.h"
+
+namespace NR {
+
+class Filter {
+public:
+    int render(NRArenaItem const *item, NRPixBlock *pb);
+    
+    int set_parameter(int identifier, int parameter, int value);
+    int set_input(int identifier, int input, int slot);
+    int set_output(int identifier, int output, int slot);
+
+    Filter();
+    Filter(int n);
+    ~Filter();
+
+private:
+    int _primitive_count;
+    int _slot_count;
+
+    FilterPrimitive ** _primitive;
+};
+
+
+} /* namespace NR */
+
+
+
+
+#endif /* __NR_FILTER_H__ */
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
Index: src/display/nr-filter-gaussian.cpp
===================================================================
--- src/display/nr-filter-gaussian.cpp	(revision 0)
+++ src/display/nr-filter-gaussian.cpp	(revision 0)
@@ -0,0 +1,114 @@
+#define __NR_FILTER_GAUSSIAN_CPP__
+
+/*
+ * Gaussian blur renderer
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <cmath>
+#include "display/nr-filter-gaussian.h"
+#include "libnr/nr-pixblock.h"
+
+namespace NR {
+
+FilterGaussian::FilterGaussian()
+{
+    _deviation_x = _deviation_y = 2.0;
+}
+
+int FilterGaussian::render(NRPixBlock **pb)
+{
+    NRPixBlock *in = pb[0];
+    NRPixBlock *mid = new NRPixBlock;
+    NRPixBlock *out = new NRPixBlock;
+
+    nr_pixblock_setup_fast(mid, in->mode, in->area.x0, in->area.y0,
+                           in->area.x1, in->area.y1, true);
+    nr_pixblock_setup_fast(out, in->mode, in->area.x0, in->area.y0,
+                           in->area.x1, in->area.y1, true);
+
+    mid->visible_area = in->visible_area;
+    out->visible_area = in->visible_area;
+
+    int length_x = (int)std::ceil(_deviation_x * 3.0);
+    int length_y = (int)std::ceil(_deviation_y * 3.0);
+    int kernel_len_x = length_x * 2 + 1;
+    int kernel_len_y = length_y * 2 + 1;
+    double kernel[(kernel_len_x > kernel_len_y) ? kernel_len_x : kernel_len_y];
+    
+    /* Blur in direction of X-axis */
+    for ( int i = 0; i < kernel_len_x ; i++ ) {
+        double d_sq = _deviation_x * _deviation_x;
+        double i_sq = (i - length_x) * (i - length_x);
+        kernel[i] = std::exp(-i_sq / (2 * d_sq)) / std::sqrt(2 * M_PI * d_sq);
+    }
+
+    for ( int y = mid->area.y0 ; y < mid->area.y1 ; y++ ) {
+        int in_line  = (y - in->area.y0)  * in->rs;
+        int mid_line = (y - mid->area.y0) * mid->rs;
+        for ( int x = mid->area.x0 ; x < mid->area.x1 ; x++ ) {
+            for ( int byte = 0 ; byte < NR_PIXBLOCK_BPP(in) ; byte++) {
+                double sum = 0;
+                for ( int i = -length_x ; i <= length_x ; i++ ) {
+                    if ((x + i) >= in->area.x0 && (x + i) < in->area.x1) {
+                        sum += NR_PIXBLOCK_PX(in)[in_line + NR_PIXBLOCK_BPP(in) * (x - in->area.x0 + i) + byte] * kernel[i + length_x];
+                    }
+                }
+                NR_PIXBLOCK_PX(mid)[mid_line + NR_PIXBLOCK_BPP(mid) * (x - mid->area.x0) + byte] = (unsigned char)sum;
+            }
+        }
+    }
+
+    /* Blur in direction of Y-axis */
+    if(_deviation_x != _deviation_y) {
+        for ( int i = 0; i < kernel_len_y ; i++ ) {
+            double d_sq = _deviation_y * _deviation_y;
+            double i_sq = (i - length_y) * (i - length_y);
+            kernel[i] = std::exp(-i_sq / (2 * d_sq)) / std::sqrt(2 * M_PI * d_sq);
+        }
+    }
+
+    for ( int y = out->area.y0 ; y < out->area.y1 ; y++ ) {
+        int out_line = (y - out->area.y0) * out->rs;
+        for ( int x = out->area.x0 ; x < out->area.x1 ; x++ ) {
+            int mid_disp = NR_PIXBLOCK_BPP(mid) * (x - mid->area.x0);
+            int out_disp = NR_PIXBLOCK_BPP(out) * (x - out->area.x0);
+            for ( int byte = 0 ; byte < NR_PIXBLOCK_BPP(mid) ; byte++) {
+                double sum = 0;
+                for ( int i = -length_y ; i <= length_y ; i++ ) {
+                    if((y + i) >= mid->area.y0 && (y + i) < mid->area.y1) {
+                        sum += NR_PIXBLOCK_PX(mid)[(y - mid->area.y0 + i) * mid->rs + mid_disp + byte] * kernel[i + length_x];
+                    }
+                }
+                NR_PIXBLOCK_PX(out)[out_line + out_disp + byte] = (unsigned char)sum;
+            }
+        }
+    }
+
+    nr_pixblock_release(mid);
+    delete mid;
+
+    out->empty = FALSE;
+    pb[1] = out;
+
+    return 0;
+}
+
+} /* namespace NR */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
Index: src/display/nr-filter-primitive.h
===================================================================
--- src/display/nr-filter-primitive.h	(revision 0)
+++ src/display/nr-filter-primitive.h	(revision 0)
@@ -0,0 +1,44 @@
+#ifndef __NR_FILTER_PRIMITIVE_H__
+#define __NR_FILTER_PRIMITIVE_H__
+
+/*
+ * SVG filters rendering
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "libnr/nr-pixblock.h"
+
+namespace NR {
+
+class FilterPrimitive {
+public:
+    FilterPrimitive();
+    virtual int render(NRPixBlock **pb) = 0;
+
+private:
+
+};
+
+
+} /* namespace NR */
+
+
+
+
+#endif /* __NR_FILTER_PRIMITIVE_H__ */
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
Index: src/display/Makefile_insert
===================================================================
--- src/display/Makefile_insert	(revision 12088)
+++ src/display/Makefile_insert	(working copy)
@@ -60,7 +60,13 @@
 	display/sp-ctrlline.cpp	\
 	display/sp-ctrlline.h \
 	display/sp-ctrlquadr.cpp \
-	display/sp-ctrlquadr.h 
+	display/sp-ctrlquadr.h \
+	display/nr-filter.cpp           \
+	display/nr-filter.h             \
+	display/nr-filter-primitive.cpp \
+	display/nr-filter-primitive.h   \
+	display/nr-filter-gaussian.cpp  \
+	display/nr-filter-gaussian.h
 
 display_bezier_utils_test_SOURCES = display/bezier-utils-test.cpp
 display_bezier_utils_test_LDADD = libnr/libnr.a -lglib-2.0
Index: src/display/nr-filter.cpp
===================================================================
--- src/display/nr-filter.cpp	(revision 0)
+++ src/display/nr-filter.cpp	(revision 0)
@@ -0,0 +1,104 @@
+#define __NR_FILTER_CPP__
+
+/*
+ * SVG filters rendering
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "display/nr-filter.h"
+#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-gaussian.h"
+
+#include "display/nr-arena-item.h"
+#include "libnr/nr-pixblock.h"
+#include "libnr/nr-blit.h"
+
+namespace NR {
+
+Filter::Filter()
+{
+    _primitive_count = 1;
+    _slot_count = 2;
+    _primitive = new FilterPrimitive*[1];
+    _primitive[0] = new FilterGaussian;
+}
+
+Filter::Filter(int n)
+{
+    _primitive_count = n;
+    _slot_count = 2;
+    _primitive = new FilterPrimitive*[n];
+    _primitive[0] = new FilterGaussian;
+    for ( int i = 1 ; i < n ; i++ ) {
+        _primitive[i] = NULL;
+    }
+}
+
+Filter::~Filter()
+{
+    for ( int i = 0 ; i < _primitive_count ; i++ ) {
+        if (_primitive[i]) {
+            delete _primitive[i];
+        }
+    }
+    delete[] _primitive;
+}
+
+
+int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
+{
+    NRPixBlock *slot[2];
+    slot[0] = pb;
+    slot[1] = NULL;
+
+    _primitive[0]->render(slot);
+
+
+    int size = (slot[0]->area.x1 - slot[0]->area.x0)
+        * (slot[0]->area.y1 - slot[0]->area.y0)
+        * NR_PIXBLOCK_BPP(slot[0]);
+    memset(NR_PIXBLOCK_PX(slot[0]), 0, size);
+
+    nr_blit_pixblock_pixblock(slot[0], slot[1]);
+
+    nr_pixblock_release(slot[1]);
+
+    return 0;
+}
+
+int Filter::set_parameter(int identifier, int parameter, int value)
+{
+
+    return -1;
+}
+
+int Filter::set_input(int identifier, int input, int slot)
+{
+
+    return -1;
+}
+
+int Filter::set_output(int identifier, int output, int slot)
+{
+
+    return -1;
+}
+
+} /* namespace NR */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
Index: src/display/nr-filter-primitive.cpp
===================================================================
--- src/display/nr-filter-primitive.cpp	(revision 0)
+++ src/display/nr-filter-primitive.cpp	(revision 0)
@@ -0,0 +1,34 @@
+#define __NR_FILTER_PRIMITIVE_CPP__
+
+/*
+ * SVG filters rendering
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "nr-filter-primitive.h"
+#include "libnr/nr-pixblock.h"
+
+namespace NR {
+
+FilterPrimitive::FilterPrimitive()
+{
+}
+
+} /* namespace NR */
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
Index: src/display/nr-filter-gaussian.h
===================================================================
--- src/display/nr-filter-gaussian.h	(revision 0)
+++ src/display/nr-filter-gaussian.h	(revision 0)
@@ -0,0 +1,48 @@
+#ifndef __NR_FILTER_GAUSSIAN_H__
+#define __NR_FILTER_GAUSSIAN_H__
+
+/*
+ * Gaussian blur renderer
+ *
+ * Author:
+ *   Niko Kiirala <niko@...1267...>
+ *
+ * Copyright (C) 2006 Niko Kiirala
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "display/nr-filter-primitive.h"
+#include "libnr/nr-pixblock.h"
+
+namespace NR {
+
+class FilterGaussian : public FilterPrimitive {
+public:
+    FilterGaussian();
+    
+    virtual int render(NRPixBlock **pb);
+
+private:
+    double _deviation_x;
+    double _deviation_y;
+
+};
+
+
+} /* namespace NR */
+
+
+
+
+#endif /* __NR_FILTER_GAUSSIAN_H__ */
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
