From f727367dddbf050f0a7d33757e9290f571cbd492 Mon Sep 17 00:00:00 2001 From: kiirala Date: Mon, 21 May 2007 09:39:52 +0000 Subject: [PATCH] Refactoring work for filter effects renderer initialization --- src/display/nr-arena-group.cpp | 80 +++++++++++++--------------------- src/display/nr-arena-image.cpp | 80 +++++++++++++--------------------- src/display/nr-arena-shape.cpp | 49 ++++----------------- src/display/nr-filter.cpp | 37 ++++++++-------- src/display/nr-filter.h | 19 +++++--- src/sp-feblend.cpp | 41 ++++++++++++++--- src/sp-filter-primitive.cpp | 18 +++++++- src/sp-filter-primitive.h | 31 ++++++++++++- src/sp-filter.cpp | 33 +++++++++++++- src/sp-filter.h | 20 +++++++-- src/sp-gaussian-blur.cpp | 47 +++++++++++++++----- 11 files changed, 266 insertions(+), 189 deletions(-) diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp index 697ef6a05..da3a240a6 100644 --- a/src/display/nr-arena-group.cpp +++ b/src/display/nr-arena-group.cpp @@ -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; ifilter.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 : diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 964f7e86f..5f22dc5cd 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -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; ifilter.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 : diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 421627309..c09bdb9dd 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -28,15 +28,10 @@ #include #include #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 @@ -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; ifilter.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; } diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index fe33afff0..515d5961f 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -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() diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index c1012475c..a6f71b9a5 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -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. diff --git a/src/sp-feblend.cpp b/src/sp-feblend.cpp index 55c387e00..49ab18a25 100644 --- a/src/sp-feblend.cpp +++ b/src/sp-feblend.cpp @@ -25,7 +25,10 @@ #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(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_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: diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 7be694980..f799dbe54 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -7,8 +7,9 @@ /* * Authors: * Kees Cook + * Niko Kiirala * - * 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: diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index 3a41f52de..96268dbfe 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -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 + * Niko Kiirala + * + * 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 : diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index a27dfd124..ac0d3d29e 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -6,8 +6,9 @@ /* * Authors: * Hugo Rodrigues + * Niko Kiirala * - * 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: diff --git a/src/sp-filter.h b/src/sp-filter.h index 68f7f0a1c..06b46ecc6 100644 --- a/src/sp-filter.h +++ b/src/sp-filter.h @@ -7,8 +7,9 @@ /* * Authors: * Hugo Rodrigues + * Niko Kiirala * - * 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 */ diff --git a/src/sp-gaussian-blur.cpp b/src/sp-gaussian-blur.cpp index 7410587e3..bc65574ca 100644 --- a/src/sp-gaussian-blur.cpp +++ b/src/sp-gaussian-blur.cpp @@ -6,9 +6,10 @@ */ /* * Authors: - * hugo Rodrigues + * Hugo Rodrigues + * Niko Kiirala * - * Copyright (C) 2006 Hugo Rodrigues + * Copyright (C) 2006,2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -22,6 +23,11 @@ #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_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: -- 2.30.2