Code

Refactoring work for filter effects renderer initialization
authorkiirala <kiirala@users.sourceforge.net>
Mon, 21 May 2007 09:39:52 +0000 (09:39 +0000)
committerkiirala <kiirala@users.sourceforge.net>
Mon, 21 May 2007 09:39:52 +0000 (09:39 +0000)
src/display/nr-arena-group.cpp
src/display/nr-arena-image.cpp
src/display/nr-arena-shape.cpp
src/display/nr-filter.cpp
src/display/nr-filter.h
src/sp-feblend.cpp
src/sp-filter-primitive.cpp
src/sp-filter-primitive.h
src/sp-filter.cpp
src/sp-filter.h
src/sp-gaussian-blur.cpp

index 697ef6a056af17486335b46001763067593c099c..da3a240a64558a98bd41c242693d829d37cface8 100644 (file)
@@ -187,59 +187,30 @@ nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int
 
 void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style)
 {
-  g_return_if_fail(group != NULL);
-  g_return_if_fail(NR_IS_ARENA_GROUP(group));
-
-  if (style) sp_style_ref(style);
-  if (group->style) sp_style_unref(group->style);
-  group->style = style;
-
-  //if there is a filter set for this group
-  if (style && style->filter.set && style->filter.filter) {
-  
-        group->filter = new NR::Filter();
-        group->filter->set_x(style->filter.filter->x);
-        group->filter->set_y(style->filter.filter->y);
-        group->filter->set_width(style->filter.filter->width);
-        group->filter->set_height(style->filter.filter->height);
-        
-        //go through all SP filter primitives
-        for(int i=0; i<style->filter.filter->_primitive_count; i++)
-        {
-            SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
-            //if primitive is gaussianblur
-            if(SP_IS_GAUSSIANBLUR(primitive))
-            {
-                NR::FilterGaussian * gaussian = (NR::FilterGaussian *) group->filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
-                SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
-                float num = spblur->stdDeviation.getNumber();
-                if( num>=0.0 )
-                {
-                    float optnum = spblur->stdDeviation.getOptNumber();
-                    if( optnum>=0.0 )
-                        gaussian->set_deviation((double) num, (double) optnum);
-                    else
-                        gaussian->set_deviation((double) num);
-                }
-            } else if(SP_IS_FEBLEND(primitive)) {
-                // TODO: this is just a test. Besides this whole filter
-                // creation needs to be redone
-                NR::FilterBlend *nrblend = (NR::FilterBlend *) group->filter->add_primitive(NR::NR_FILTER_BLEND);
-                SPFeBlend *spblend = SP_FEBLEND(primitive);
-                nrblend->set_mode(spblend->blend_mode);
-            }
+    g_return_if_fail(group != NULL);
+    g_return_if_fail(NR_IS_ARENA_GROUP(group));
+
+    if (style) sp_style_ref(style);
+    if (group->style) sp_style_unref(group->style);
+    group->style = style;
+
+    //if group has a filter
+    if (style->filter.set && style->filter.filter) {
+        if (!group->filter) {
+            int primitives = sp_filter_primitive_count(style->filter.filter);
+            group->filter = new NR::Filter(primitives);
         }
-    }
-    else
-    {
+        sp_filter_build_renderer(style->filter.filter, group->filter);
+    } else {
         //no filter set for this group
+        delete group->filter;
         group->filter = NULL;
     }
-
-  if (style && style->enable_background.set
-      && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
-    group->background_new = true;
-  }
+  
+    if (style && style->enable_background.set
+        && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
+        group->background_new = true;
+    }
 }
 
 static unsigned int
@@ -314,4 +285,13 @@ void nr_arena_group_set_child_transform(NRArenaGroup *group, NRMatrix const *t)
        }
 }
 
-
+/*
+  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 964f7e86f769661c9b282f1f33d7de0c1e0e6f8c..5f22dc5cd5010c0ffd53e2e5ea1339faaf30d45a 100644 (file)
@@ -360,57 +360,39 @@ nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double wid
 
 void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style)
 {
-  g_return_if_fail(image != NULL);
-  g_return_if_fail(NR_IS_ARENA_IMAGE(image));
-
-  if (style) sp_style_ref(style);
-  if (image->style) sp_style_unref(image->style);
-  image->style = style;
-
-  //if there is a filter set for this group
-  if (style && style->filter.set && style->filter.filter) {
-  
-        image->filter = new NR::Filter();
-        image->filter->set_x(style->filter.filter->x);
-        image->filter->set_y(style->filter.filter->y);
-        image->filter->set_width(style->filter.filter->width);
-        image->filter->set_height(style->filter.filter->height);
-        
-        //go through all SP filter primitives
-        for(int i=0; i<style->filter.filter->_primitive_count; i++)
-        {
-            SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
-            //if primitive is gaussianblur
-            if(SP_IS_GAUSSIANBLUR(primitive))
-            {
-                NR::FilterGaussian * gaussian = (NR::FilterGaussian *) image->filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
-                SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
-                float num = spblur->stdDeviation.getNumber();
-                if( num>=0.0 )
-                {
-                    float optnum = spblur->stdDeviation.getOptNumber();
-                    if( optnum>=0.0 )
-                        gaussian->set_deviation((double) num, (double) optnum);
-                    else
-                        gaussian->set_deviation((double) num);
-                }
-            } else if(SP_IS_FEBLEND(primitive)) {
-                // TODO: this is just a test. Besides this whole filter
-                // creation needs to be redone
-                NR::FilterBlend *nrblend = (NR::FilterBlend *) image->filter->add_primitive(NR::NR_FILTER_BLEND);
-                SPFeBlend *spblend = SP_FEBLEND(primitive);
-                nrblend->set_mode(spblend->blend_mode);
-            }
+    g_return_if_fail(image != NULL);
+    g_return_if_fail(NR_IS_ARENA_IMAGE(image));
+
+    if (style) sp_style_ref(style);
+    if (image->style) sp_style_unref(image->style);
+    image->style = style;
+
+    //if image has a filter
+    if (style->filter.set && style->filter.filter) {
+        if (!image->filter) {
+            int primitives = sp_filter_primitive_count(style->filter.filter);
+            image->filter = new NR::Filter(primitives);
         }
-    }
-    else
-    {
-        //no filter set for this group
+        sp_filter_build_renderer(style->filter.filter, image->filter);
+    } else {
+        //no filter set for this image
+        delete image->filter;
         image->filter = NULL;
     }
 
-  if (style && style->enable_background.set
-      && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
-    image->background_new = true;
-  }
+    if (style && style->enable_background.set
+        && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
+        image->background_new = true;
+    }
 }
+
+/*
+  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 421627309d5f5e7648bd19cae0772b7d4f72437b..c09bdb9dd9e1a405937d9a5f6edcb8a946c7640e 100644 (file)
 #include <livarot/int-line.h>
 #include <style.h>
 #include "prefs-utils.h"
-#include "sp-filter.h"
 #include "inkscape-cairo.h"
 
+#include "sp-filter.h"
 #include "display/nr-filter.h"
-#include "display/nr-filter-gaussian.h"
-#include "display/nr-filter-types.h"
-#include "sp-gaussian-blur.h"
-#include "sp-feblend.h"
-#include "display/nr-filter-blend.h"
 
 #include <cairo.h>
 
@@ -1364,43 +1359,15 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style)
     shape->setMitreLimit(style->stroke_miterlimit.value);
 
     //if shape has a filter
-    if (style->filter.set && style->filter.filter) 
-    {
-        shape->filter = new NR::Filter();
-        shape->filter->set_x(style->filter.filter->x);
-        shape->filter->set_y(style->filter.filter->y);
-        shape->filter->set_width(style->filter.filter->width);
-        shape->filter->set_height(style->filter.filter->height);
-        
-        //go through all SP filter primitives
-        for(int i=0; i<style->filter.filter->_primitive_count; i++)
-        {
-            SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
-            //if primitive is gaussianblur
-            if(SP_IS_GAUSSIANBLUR(primitive)) {
-                NR::FilterGaussian * gaussian = (NR::FilterGaussian *) shape->filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
-                SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
-                float num = spblur->stdDeviation.getNumber();
-                if( num>=0.0 )
-                {
-                    float optnum = spblur->stdDeviation.getOptNumber();
-                    if( optnum>=0.0 )
-                        gaussian->set_deviation((double) num, (double) optnum);
-                    else
-                        gaussian->set_deviation((double) num);
-                }
-            } else if(SP_IS_FEBLEND(primitive)) {
-                // TODO: this is just a test. Besides this whole filter
-                // creation needs to be redone
-                NR::FilterBlend *nrblend = (NR::FilterBlend *) shape->filter->add_primitive(NR::NR_FILTER_BLEND);
-                SPFeBlend *spblend = SP_FEBLEND(primitive);
-                nrblend->set_mode(spblend->blend_mode);
-            }
+    if (style->filter.set && style->filter.filter) {
+        if (!shape->filter) {
+            int primitives = sp_filter_primitive_count(style->filter.filter);
+            shape->filter = new NR::Filter(primitives);
         }
-    }
-    else
-    {
+        sp_filter_build_renderer(style->filter.filter, shape->filter);
+    } else {
         //no filter set for this shape
+        delete shape->filter;
         shape->filter = NULL;
     }
 
index fe33afff0b56cb2f3eac244cd663a78231587f0b..515d5961f0d5a578f88e67b8114f36ebac30091e 100644 (file)
@@ -348,14 +348,14 @@ void Filter::_enlarge_primitive_table() {
     _primitive = new_tbl;
 }
 
-FilterPrimitive *Filter::add_primitive(FilterPrimitiveType type)
+int Filter::add_primitive(FilterPrimitiveType type)
 {
     _create_constructor_table();
 
     // Check that we can create a new filter of specified type
     if (type < 0 || type >= NR_FILTER_ENDPRIMITIVETYPE)
-        return NULL;
-    if (!_constructor[type]) return NULL;
+        return -1;
+    if (!_constructor[type]) return -1;
     FilterPrimitive *created = _constructor[type]();
 
     // If there is no space for new filter primitive, enlarge the table
@@ -364,28 +364,24 @@ FilterPrimitive *Filter::add_primitive(FilterPrimitiveType type)
     }
 
     _primitive[_primitive_count] = created;
+    int handle = _primitive_count;
     _primitive_count++;
-    return created;
+    return handle;
 }
 
-FilterPrimitive *Filter::replace_primitive(FilterPrimitive *target, FilterPrimitiveType type)
+int Filter::replace_primitive(int target, FilterPrimitiveType type)
 {
     _create_constructor_table();
 
     // Check that target is valid primitive inside this filter
-    int place = -1;
-    for (int i = 0 ; i < _primitive_count ; i++) {
-        if (target == _primitive[i]) {
-            place = i;
-            break;
-        }
-    }
-    if (place < 0) return NULL;
+    if (target < 0) return -1;
+    if (target >= _primitive_count) return -1;
+    if (!_primitive[target]) return -1;
 
     // Check that we can create a new filter of specified type
     if (type < 0 || type >= NR_FILTER_ENDPRIMITIVETYPE)
-        return NULL;
-    if (!_constructor[type]) return NULL;
+        return -1;
+    if (!_constructor[type]) return -1;
     FilterPrimitive *created = _constructor[type]();
 
     // If there is no space for new filter primitive, enlarge the table
@@ -393,9 +389,14 @@ FilterPrimitive *Filter::replace_primitive(FilterPrimitive *target, FilterPrimit
         _enlarge_primitive_table();
     }
 
-    delete target;
-    _primitive[place] = created;
-    return created;
+    delete _primitive[target];
+    _primitive[target] = created;
+    return target;
+}
+
+FilterPrimitive *Filter::get_primitive(int handle) {
+    if (handle < 0 || handle >= _primitive_count) return NULL;
+    return _primitive[handle];
 }
 
 void Filter::clear_primitives()
index c1012475c3bdb3bb2e715e616e1332422a3e98c4..a6f71b9a56ca4d1f181ee36ca369b714d6c2943a 100644 (file)
@@ -37,11 +37,11 @@ public:
      * Should this filter not have enough space for a new primitive, the filter
      * is enlarged to accomodate the new filter element. It may be enlarged by
      * more that one element.
-     * Returns a pointer to the filter primitive created.
-     * Returns NULL, if type is not valid filter primitive type or filter
+     * Returns a handle (non-negative integer) to the filter primitive created.
+     * Returns -1, if type is not valid filter primitive type or filter
      * primitive of such type cannot be created.
      */
-    FilterPrimitive *add_primitive(FilterPrimitiveType type);
+    int add_primitive(FilterPrimitiveType type);
     /**
      * Removes all filter primitives from this filter.
      * All pointers to filter primitives inside this filter should be
@@ -54,14 +54,19 @@ public:
      * If 'target' does not correspond to any primitive inside this filter OR
      * 'type' is not a valid filter primitive type OR
      * filter primitive of such type cannot be created,
-     * this function returns NULL and doesn't change the internal state of this
+     * this function returns -1 and doesn't change the internal state of this
      * filter.
      * Otherwise, a new filter primitive is created. Any pointers to filter
-     * primitive 'target' should be considered invalid. A pointer to the
+     * primitive 'target' should be considered invalid. A handle to the
      * newly created primitive is returned.
      */
-    FilterPrimitive *replace_primitive(FilterPrimitive *primitive,
-                                       FilterPrimitiveType type);
+    int replace_primitive(int primitive, FilterPrimitiveType type);
+
+    /**
+     * Returns a pointer to the primitive, which the handle corrensponds to.
+     * If the handle is not valid, returns NULL.
+     */
+    FilterPrimitive *get_primitive(int handle);
 
     /**
      * Sets the slot number 'slot' to be used as result from this filter.
index 55c387e0036570e92ee7a7ffdd3a8c7ac3ec72e0..49ab18a25fcf7c25343d01f8e90d9e797a6c085a 100644 (file)
 #include "sp-feblend.h"
 #include "xml/repr.h"
 
+#include "display/nr-filter.h"
+#include "display/nr-filter-primitive.h"
 #include "display/nr-filter-blend.h"
+#include "display/nr-filter-types.h"
 
 /* FeBlend base class */
 
@@ -37,8 +40,10 @@ static void sp_feBlend_release(SPObject *object);
 static void sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value);
 static void sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags);
 static Inkscape::XML::Node *sp_feBlend_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static void sp_feBlend_build_renderer(SPFilterPrimitive *sp_prim, NR::Filter *filter);
 
 static SPFilterPrimitiveClass *feBlend_parent_class;
+static int renderer;
 
 GType
 sp_feBlend_get_type()
@@ -65,6 +70,7 @@ static void
 sp_feBlend_class_init(SPFeBlendClass *klass)
 {
     SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+    SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass;
 
     feBlend_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass);
 
@@ -73,11 +79,14 @@ sp_feBlend_class_init(SPFeBlendClass *klass)
     sp_object_class->write = sp_feBlend_write;
     sp_object_class->set = sp_feBlend_set;
     sp_object_class->update = sp_feBlend_update;
+
+    sp_primitive_class->build_renderer = sp_feBlend_build_renderer;
 }
 
 static void
 sp_feBlend_init(SPFeBlend *feBlend)
 {
+    renderer = -1;
 }
 
 /**
@@ -150,6 +159,14 @@ sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value)
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
         case SP_ATTR_MODE:
             feBlend->blend_mode = sp_feBlend_readmode(value);
+/*
+            if (renderer >= 0) {
+                NR::Filter *filter = SP_FILTER(object->parent)->_renderer;
+                NR::FilterBlend *blend = dynamic_cast<NR::FilterBlend*>(filter->get_primitive(renderer));
+                blend->set_mode(feBlend->blend_mode);
+            }
+*/
+            object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         default:
             if (((SPObjectClass *) feBlend_parent_class)->set)
@@ -165,11 +182,8 @@ sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value)
 static void
 sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags)
 {
-    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
-                 SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-
-        /* do something to trigger redisplay, updates? */
-
+    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) {
+        sp_object_read_attr(object, "mode");
     }
 
     if (((SPObjectClass *) feBlend_parent_class)->update) {
@@ -200,6 +214,23 @@ sp_feBlend_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
     return repr;
 }
 
+static void sp_feBlend_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+    g_assert(primitive != NULL);
+    g_assert(filter != NULL);
+
+    SPFeBlend *sp_blend = SP_FEBLEND(primitive);
+
+    int primitive_n = filter->add_primitive(NR::NR_FILTER_BLEND);
+    NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
+    NR::FilterBlend *nr_blend = dynamic_cast<NR::FilterBlend*>(nr_primitive);
+    g_assert(nr_blend != NULL);
+
+    sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+    nr_blend->set_mode(sp_blend->blend_mode);
+
+    renderer = primitive_n;
+}
 
 /*
   Local Variables:
index 7be694980afdde0bcbae5def9a6aee80579bf3dc..f799dbe5432c4a8ebee7e3d4cfa173a926d9833b 100644 (file)
@@ -7,8 +7,9 @@
 /*
  * Authors:
  *   Kees Cook <kees@outflux.net>
+ *   Niko Kiirala <niko@kiirala.com>
  *
- * Copyright (C) 2004 Kees Cook
+ * Copyright (C) 2004-2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -21,6 +22,7 @@
 #include "sp-filter-primitive.h"
 #include "xml/repr.h"
 #include "sp-filter.h"
+#include "display/nr-filter-primitive.h"
 
 /* FilterPrimitive base class */
 
@@ -69,6 +71,10 @@ sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass)
     sp_object_class->write = sp_filter_primitive_write;
     sp_object_class->set = sp_filter_primitive_set;
     sp_object_class->update = sp_filter_primitive_update;
+    
+    /* This should never be called on this base class, but only on derived
+     * classes. */
+    klass->build_renderer = NULL;
 }
 
 static void
@@ -163,6 +169,16 @@ sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint fla
     return repr;
 }
 
+/* Common initialization for filter primitives */
+void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, NR::FilterPrimitive *nr_prim)
+{
+    g_assert(sp_prim != NULL);
+    g_assert(nr_prim != NULL);
+
+    /* TODO: place here code to handle input images, filter area etc. */
+}
+
+
 
 /*
   Local Variables:
index 3a41f52de08fdfd25463b9f728b529c3e78caea3..96268dbfe9da631dae61a7f888f9928f201ffe05 100644 (file)
@@ -1,9 +1,22 @@
 #ifndef __SP_FILTER_PRIMITIVE_H__
 #define __SP_FILTER_PRIMITIVE_H__
 
+/** \file
+ * Document level base class for all SVG filter primitives.
+ */
+/*
+ * Authors:
+ *   Hugo Rodrigues <haa.rodrigues@gmail.com>
+ *   Niko Kiirala <niko@kiirala.com>
+ *
+ * Copyright (C) 2006,2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
 
 #include "sp-object.h"
-
+#include "display/nr-filter.h"
+#include "display/nr-filter-primitive.h"
 
 #define SP_TYPE_FILTER_PRIMITIVE (sp_filter_primitive_get_type ())
 #define SP_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitive))
@@ -18,9 +31,23 @@ struct SPFilterPrimitive : public SPObject {
 };
 
 struct SPFilterPrimitiveClass {
-       SPObjectClass sp_object_class;
+    SPObjectClass sp_object_class;
+    void (* build_renderer)(SPFilterPrimitive*, NR::Filter*);
 };
 
 GType sp_filter_primitive_get_type (void);
 
+/* Common initialization for filter primitives */
+void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, NR::FilterPrimitive *nr_prim);
+
 #endif
+/*
+  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 a27dfd124d6c36830601ead0956f8beb1927c294..ac0d3d29ec53f4aabc1abc6b379eb94aaea40c35 100644 (file)
@@ -6,8 +6,9 @@
 /*
  * Authors:
  *   Hugo Rodrigues <haa.rodrigues@gmail.com>
+ *   Niko Kiirala <niko@kiirala.com>
  *
- * Copyright (C) 2006 Hugo Rodrigues
+ * Copyright (C) 2006,2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -26,6 +27,7 @@
 #define SP_MACROS_SILENT
 #include "macros.h"
 
+#include "display/nr-filter.cpp"
 
 /* Filter base class */
 
@@ -106,6 +108,7 @@ sp_filter_init(SPFilter *filter)
     filter->_primitives = new SPFilterPrimitive*[1];
     filter->_primitives[0] = NULL;
 
+    filter->_renderer = NULL;
 }
 
 /**
@@ -422,6 +425,34 @@ sp_filter_remove_child(SPObject *object, Inkscape::XML::Node *child)
        */
 }
 
+void sp_filter_build_renderer(SPFilter *sp_filter, NR::Filter *nr_filter)
+{
+    g_assert(sp_filter != NULL);
+    g_assert(nr_filter != NULL);
+
+    sp_filter->_renderer = nr_filter;
+
+    nr_filter->set_x(sp_filter->x);
+    nr_filter->set_y(sp_filter->y);
+    nr_filter->set_width(sp_filter->width);
+    nr_filter->set_height(sp_filter->height);
+
+    nr_filter->clear_primitives();
+    for (int i = 0 ; i < sp_filter->_primitive_count ; i++) {
+        SPFilterPrimitive *primitive = sp_filter->_primitives[i];
+        g_assert(primitive != NULL);
+        if (((SPFilterPrimitiveClass*) G_OBJECT_GET_CLASS(primitive))->build_renderer) {
+            ((SPFilterPrimitiveClass *) G_OBJECT_GET_CLASS(primitive))->build_renderer(primitive, nr_filter);
+        } else {
+            g_warning("Cannot build filter renderer: missing builder");
+        }
+    }
+}
+
+int sp_filter_primitive_count(SPFilter *filter) {
+    g_assert(filter != NULL);
+    return filter->_primitive_count;
+}
 
 /*
   Local Variables:
index 68f7f0a1c4a7ed777befbd8e27b57e967df5ea1c..06b46ecc6d087a804a3f3e6cb993805ea6262f6f 100644 (file)
@@ -7,8 +7,9 @@
 /*
  * Authors:
  *   Hugo Rodrigues <haa.rodrigues@gmail.com>
+ *   Niko Kiirala <niko@kiirala.com>
  *
- * Copyright (C) 2006 Hugo Rodrigues
+ * Copyright (C) 2006,2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -18,6 +19,7 @@
 #include "sp-filter-units.h"
 #include "sp-filter-fns.h"
 #include "svg/svg-length.h"
+#include "display/nr-filter.h"
 
 /* Filter base class */
 
@@ -49,16 +51,26 @@ struct SPFilter : public SPObject {
     /** HREF attribute */
     SPFilterReference *href;
 
-       int _primitive_count;
-       int _primitive_table_size;
-       SPFilterPrimitive ** _primitives;
+    int _primitive_count;
+    int _primitive_table_size;
+    SPFilterPrimitive ** _primitives;
+    NR::Filter *_renderer;
 };
 
 struct SPFilterClass {
     SPObjectClass parent_class;
 };
 
+/*
+ * Initializes the given NR::Filter object as a renderer for this
+ * SPFilter object.
+ */
+void sp_filter_build_renderer(SPFilter *sp_filter, NR::Filter *nr_filter);
 
+/*
+ * Returns the number of filter primitives in this SPFilter object.
+ */
+int sp_filter_primitive_count(SPFilter *filter);
 
 #endif /* !SP_FILTER_H_SEEN */
 
index 7410587e3f1f382130cfd32f75fe2dfb481fd1e6..bc65574ca6982dd9311b3294ce788e5755651e65 100644 (file)
@@ -6,9 +6,10 @@
  */
 /*
  * Authors:
- *   hugo Rodrigues <haa.rodrigues@gmail.com>
+ *   Hugo Rodrigues <haa.rodrigues@gmail.com>
+ *   Niko Kiirala <niko@kiirala.com>
  *
- * Copyright (C) 2006 Hugo Rodrigues
+ * Copyright (C) 2006,2007 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #include "sp-gaussian-blur.h"
 #include "xml/repr.h"
 
+#include "display/nr-filter.h"
+#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-gaussian.h"
+#include "display/nr-filter-types.h"
+
 //#define SP_MACROS_SILENT
 //#include "macros.h"
 
@@ -35,6 +41,7 @@ static void sp_gaussianBlur_release(SPObject *object);
 static void sp_gaussianBlur_set(SPObject *object, unsigned int key, gchar const *value);
 static void sp_gaussianBlur_update(SPObject *object, SPCtx *ctx, guint flags);
 static Inkscape::XML::Node *sp_gaussianBlur_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static void sp_gaussianBlur_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter);
 
 static SPFilterPrimitiveClass *gaussianBlur_parent_class;
 
@@ -63,6 +70,7 @@ static void
 sp_gaussianBlur_class_init(SPGaussianBlurClass *klass)
 {
     SPObjectClass *sp_object_class = (SPObjectClass *)klass;
+    SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass;
 
     gaussianBlur_parent_class = (SPFilterPrimitiveClass *)g_type_class_peek_parent(klass);
 
@@ -71,6 +79,8 @@ sp_gaussianBlur_class_init(SPGaussianBlurClass *klass)
     sp_object_class->write = sp_gaussianBlur_write;
     sp_object_class->set = sp_gaussianBlur_set;
     sp_object_class->update = sp_gaussianBlur_update;
+
+    sp_primitive_class->build_renderer = sp_gaussianBlur_build_renderer;
 }
 
 static void
@@ -112,10 +122,11 @@ static void
 sp_gaussianBlur_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPGaussianBlur *gaussianBlur = SP_GAUSSIANBLUR(object);
-
+    
     switch(key) {
-    case SP_ATTR_STDDEVIATION:
-        gaussianBlur->stdDeviation.set(value);
+        case SP_ATTR_STDDEVIATION:
+            gaussianBlur->stdDeviation.set(value);
+            object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         default:
             if (((SPObjectClass *) gaussianBlur_parent_class)->set)
@@ -131,12 +142,8 @@ sp_gaussianBlur_set(SPObject *object, unsigned int key, gchar const *value)
 static void
 sp_gaussianBlur_update(SPObject *object, SPCtx *ctx, guint flags)
 {
-
-    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
-                 SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-
-        /* do something to trigger redisplay, updates? */
-
+    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) {
+        sp_object_read_attr(object, "stdDeviation");
     }
 
     if (((SPObjectClass *) gaussianBlur_parent_class)->update) {
@@ -179,6 +186,24 @@ void  sp_gaussianBlur_setDeviation(SPGaussianBlur *blur, float num, float optnum
     blur->stdDeviation.setOptNumber(optnum);
 }
 
+static void sp_gaussianBlur_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+    SPGaussianBlur *sp_blur = SP_GAUSSIANBLUR(primitive);
+
+    int handle = filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
+    NR::FilterPrimitive *nr_primitive = filter->get_primitive(handle);
+    NR::FilterGaussian *nr_blur = dynamic_cast<NR::FilterGaussian*>(nr_primitive);
+
+    sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+    gfloat num = sp_blur->stdDeviation.getNumber();
+    if (num >= 0.0) {
+        gfloat optnum = sp_blur->stdDeviation.getOptNumber();
+        if(optnum >= 0.0)
+            nr_blur->set_deviation((double) num, (double) optnum);
+        else
+            nr_blur->set_deviation((double) num);
+    }
+}
 
 /*
   Local Variables: