From 239d123ab0295968f8af7fd8227a1cf1ebb27002 Mon Sep 17 00:00:00 2001 From: kiirala Date: Fri, 20 Jul 2007 20:19:00 +0000 Subject: [PATCH] Patch from Felipe Sanches: support for feConvolveMatrix filter primitive --- AUTHORS | 2 + src/display/Makefile_insert | 2 + src/display/nr-filter-convolve-matrix.cpp | 141 ++++++++++++++++++++++ src/display/nr-filter-convolve-matrix.h | 60 +++++++++ src/display/nr-filter.cpp | 3 +- src/sp-feconvolvematrix.cpp | 101 +++++++++++++++- src/sp-feconvolvematrix.h | 15 ++- 7 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 src/display/nr-filter-convolve-matrix.cpp create mode 100644 src/display/nr-filter-convolve-matrix.h diff --git a/AUTHORS b/AUTHORS index 527dae8d8..989c3b7a7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,11 +65,13 @@ Marten Owens Jon Phillips Zdenko Podobny Alexandre Prokoudine +Jean-René Reinhard Alexey Remizov Frederic Rodrigo Hugo Rodrigues Juarez Rudsatz Xavier Conde Rueda +Felipe Sanches Christian Schaller Marco Scholten Tom von Schwerdtner diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index bc6fb3336..eaa2f584f 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -81,6 +81,8 @@ display_libspdisplay_a_SOURCES = \ display/nr-filter-specularlighting.h \ display/nr-filter-composite.h \ display/nr-filter-composite.cpp \ + display/nr-filter-convolve-matrix.cpp \ + display/nr-filter-convolve-matrix.h \ display/nr-filter-slot.cpp \ display/nr-filter-slot.h \ display/nr-filter-getalpha.cpp \ diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp new file mode 100644 index 000000000..6bdb3306e --- /dev/null +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -0,0 +1,141 @@ +/* + * feConvolveMatrix filter primitive renderer + * + * Authors: + * Felipe Corrêa da Silva Sanches + * + * Copyright (C) 2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/nr-filter-convolve-matrix.h" +#include +namespace NR { + +FilterConvolveMatrix::FilterConvolveMatrix() +{} + +FilterPrimitive * FilterConvolveMatrix::create() { + return new FilterConvolveMatrix(); +} + +FilterConvolveMatrix::~FilterConvolveMatrix() +{} + +static bool inside_area(int px, int py, int w, int h){ + if (px<0) return false; + if (py<0) return false; + if (px>w) return false; + if (py>h) return false; + return true; +} + +int FilterConvolveMatrix::render(FilterSlot &slot, Matrix const &trans) { + NRPixBlock *in = slot.get(_input); + NRPixBlock *out = new NRPixBlock; + + nr_pixblock_setup_fast(out, in->mode, + in->area.x0, in->area.y0, in->area.x1, in->area.y1, + true); + + unsigned char *in_data = NR_PIXBLOCK_PX(in); + unsigned char *out_data = NR_PIXBLOCK_PX(out); + + double result_R, result_G, result_B, result_A; + int i, j, x, y; + int width = in->area.x1 - in->area.x0; + int height = in->area.y1 - in->area.y0; + + double div=0; + + if (divisor != 0){ + div = divisor; + } else { + for (i=0;i 0 ? result_R : 0); + result_G = (result_G > 0 ? result_G : 0); + result_B = (result_B > 0 ? result_B : 0); + result_A = (result_A > 0 ? result_A : 0); + + out_data[4*( x + width*y )] = (result_R < 255 ? (unsigned char)result_R : 255); + out_data[4*( x + width*y )+1] = (result_G < 255 ? (unsigned char)result_G : 255); + out_data[4*( x + width*y )+2] = (result_B < 255 ? (unsigned char)result_B : 255); + out_data[4*( x + width*y )+3] = (result_A < 255 ? (unsigned char)result_A : 255); + } + } + + out->empty = FALSE; + slot.set(_output, out); + return 0; +} + +void FilterConvolveMatrix::set_targetX(int coord) { + targetX = coord; +} + +void FilterConvolveMatrix::set_targetY(int coord) { + targetY = coord; +} + +void FilterConvolveMatrix::set_orderX(int coord) { + orderX = coord; +} + +void FilterConvolveMatrix::set_orderY(int coord) { + orderY = coord; +} + +void FilterConvolveMatrix::set_divisor(double d) { + divisor = d; +} + +void FilterConvolveMatrix::set_bias(double b) { + bias = b; +} + +void FilterConvolveMatrix::set_kernelMatrix(std::vector &km) { + kernelMatrix = km; +} + +void FilterConvolveMatrix::area_enlarge(NRRectL &area, Matrix const &trans) +{ +} + +} /* 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 : diff --git a/src/display/nr-filter-convolve-matrix.h b/src/display/nr-filter-convolve-matrix.h new file mode 100644 index 000000000..e5b72a71f --- /dev/null +++ b/src/display/nr-filter-convolve-matrix.h @@ -0,0 +1,60 @@ +#ifndef __NR_FILTER_CONVOLVE_MATRIX_H__ +#define __NR_FILTER_CONVOLVE_MATRIX_H__ + +/* + * feConvolveMatrix filter primitive renderer + * + * Authors: + * Felipe Corrêa da Silva Sanches + * + * Copyright (C) 2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/nr-filter-primitive.h" +#include "display/nr-filter-slot.h" +#include "libnr/nr-matrix.h" +#include "libnr/nr-rect-l.h" +#include + +namespace NR { + +class FilterConvolveMatrix : public FilterPrimitive { +public: + FilterConvolveMatrix(); + static FilterPrimitive *create(); + virtual ~FilterConvolveMatrix(); + + virtual int render(FilterSlot &slot, Matrix const &trans); + virtual void area_enlarge(NRRectL &area, Matrix const &trans); + + void set_targetY(int coord); + void set_targetX(int coord); + void set_orderY(int coord); + void set_orderX(int coord); + void set_kernelMatrix(std::vector& km); + void set_bias(double b); + void set_divisor(double d); + +private: + std::vector kernelMatrix; + int targetX, targetY; + int orderX, orderY; + gdouble divisor, bias; + int dx, dy; //kernelUnitLength +}; + +} /* namespace NR */ + +#endif /* __NR_FILTER_CONVOLVE_MATRIX_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 : diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 8a22778a1..73a3df415 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -22,6 +22,7 @@ #include "display/pixblock-transform.h" #include "display/nr-filter-gaussian.h" +#include "display/nr-filter-convolve-matrix.h" #include "display/nr-filter-blend.h" #include "display/nr-filter-offset.h" #include "display/nr-filter-composite.h" @@ -314,7 +315,7 @@ void Filter::_create_constructor_table() _constructor[NR_FILTER_COLORMATRIX] = NULL; _constructor[NR_FILTER_COMPONENTTRANSFER] = NULL; _constructor[NR_FILTER_COMPOSITE] = &FilterComposite::create; - _constructor[NR_FILTER_CONVOLVEMATRIX] = NULL; + _constructor[NR_FILTER_CONVOLVEMATRIX] = &FilterConvolveMatrix::create; _constructor[NR_FILTER_DIFFUSELIGHTING] = &FilterDiffuseLighting::create; _constructor[NR_FILTER_DISPLACEMENTMAP] = NULL; _constructor[NR_FILTER_FLOOD] = NULL; diff --git a/src/sp-feconvolvematrix.cpp b/src/sp-feconvolvematrix.cpp index fe127900b..4191cceec 100644 --- a/src/sp-feconvolvematrix.cpp +++ b/src/sp-feconvolvematrix.cpp @@ -6,6 +6,7 @@ */ /* * Authors: + * Felipe Corrêa da Silva Sanches * hugo Rodrigues * * Copyright (C) 2006 Hugo Rodrigues @@ -17,11 +18,12 @@ # include "config.h" #endif +#include #include "attributes.h" #include "svg/svg.h" #include "sp-feconvolvematrix.h" #include "xml/repr.h" - +#include "display/nr-filter-convolve-matrix.h" /* FeConvolveMatrix base class */ @@ -33,6 +35,7 @@ static void sp_feConvolveMatrix_release(SPObject *object); static void sp_feConvolveMatrix_set(SPObject *object, unsigned int key, gchar const *value); static void sp_feConvolveMatrix_update(SPObject *object, SPCtx *ctx, guint flags); static Inkscape::XML::Node *sp_feConvolveMatrix_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter); static SPFilterPrimitiveClass *feConvolveMatrix_parent_class; @@ -61,6 +64,7 @@ static void sp_feConvolveMatrix_class_init(SPFeConvolveMatrixClass *klass) { SPObjectClass *sp_object_class = (SPObjectClass *)klass; + SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass; feConvolveMatrix_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass); @@ -69,11 +73,16 @@ sp_feConvolveMatrix_class_init(SPFeConvolveMatrixClass *klass) sp_object_class->write = sp_feConvolveMatrix_write; sp_object_class->set = sp_feConvolveMatrix_set; sp_object_class->update = sp_feConvolveMatrix_update; + + sp_primitive_class->build_renderer = sp_feConvolveMatrix_build_renderer; } static void sp_feConvolveMatrix_init(SPFeConvolveMatrix *feConvolveMatrix) { + feConvolveMatrix->divisor=0; + feConvolveMatrix->preserveAlpha = false; + feConvolveMatrix->order.set("3 3"); } /** @@ -89,6 +98,16 @@ sp_feConvolveMatrix_build(SPObject *object, SPDocument *document, Inkscape::XML: } /*LOAD ATTRIBUTES FROM REPR HERE*/ + sp_object_read_attr(object, "order"); + sp_object_read_attr(object, "kernelMatrix"); + sp_object_read_attr(object, "divisor"); + sp_object_read_attr(object, "bias"); + sp_object_read_attr(object, "targetX"); + sp_object_read_attr(object, "targetY"); + sp_object_read_attr(object, "edgeMode"); + sp_object_read_attr(object, "kernelUnitLength"); + sp_object_read_attr(object, "preserveAlpha"); + } /** @@ -101,6 +120,30 @@ sp_feConvolveMatrix_release(SPObject *object) ((SPObjectClass *) feConvolveMatrix_parent_class)->release(object); } + +static std::vector read_kernel_matrix(const gchar* value, int size){ + std::vector v(size, (gdouble) 0); + int i; + gchar** values = g_strsplit(value , " ", size); + for (i=0;iorder.set(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_KERNELMATRIX: + feConvolveMatrix->kernelMatrix = read_kernel_matrix(value, (int) (feConvolveMatrix->order.getNumber() * feConvolveMatrix->order.getOptNumber())); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_DIVISOR: + feConvolveMatrix->divisor = sp_feConvolveMatrix_read_number(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_BIAS: + feConvolveMatrix->bias = sp_feConvolveMatrix_read_number(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_TARGETX: + feConvolveMatrix->targetX = (int) sp_feConvolveMatrix_read_number(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_TARGETY: + feConvolveMatrix->targetY = (int) sp_feConvolveMatrix_read_number(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_EDGEMODE: + //TODO + break; + case SP_ATTR_KERNELUNITLENGTH: + feConvolveMatrix->kernelUnitLength.set(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PRESERVEALPHA: + //TODO + break; + default: if (((SPObjectClass *) feConvolveMatrix_parent_class)->set) ((SPObjectClass *) feConvolveMatrix_parent_class)->set(object, key, value); @@ -161,7 +239,28 @@ sp_feConvolveMatrix_write(SPObject *object, Inkscape::XML::Node *repr, guint fla return repr; } +static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) { + g_assert(primitive != NULL); + g_assert(filter != NULL); + + SPFeConvolveMatrix *sp_convolve = SP_FECONVOLVEMATRIX(primitive); + + int primitive_n = filter->add_primitive(NR::NR_FILTER_CONVOLVEMATRIX); + NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n); + NR::FilterConvolveMatrix *nr_convolve = dynamic_cast(nr_primitive); + g_assert(nr_convolve != NULL); + sp_filter_primitive_renderer_common(primitive, nr_primitive); + + nr_convolve->set_targetX(sp_convolve->targetX); + nr_convolve->set_targetY(sp_convolve->targetY); + nr_convolve->set_orderX( (int)sp_convolve->order.getNumber() ); + nr_convolve->set_orderY( (int)sp_convolve->order.getOptNumber() ); + nr_convolve->set_kernelMatrix(sp_convolve->kernelMatrix); + nr_convolve->set_divisor(sp_convolve->divisor); + nr_convolve->set_bias(sp_convolve->bias); + +} /* Local Variables: mode:c++ diff --git a/src/sp-feconvolvematrix.h b/src/sp-feconvolvematrix.h index d19666976..53ed8b741 100644 --- a/src/sp-feconvolvematrix.h +++ b/src/sp-feconvolvematrix.h @@ -6,6 +6,7 @@ */ /* * Authors: + * Felipe Corrêa da Silva Sanches * Hugo Rodrigues * * Copyright (C) 2006 Hugo Rodrigues @@ -15,13 +16,23 @@ #include "sp-filter.h" #include "sp-feconvolvematrix-fns.h" +#include "number-opt-number.h" +#include +//#include + /* FeConvolveMatrix base class */ class SPFeConvolveMatrixClass; struct SPFeConvolveMatrix : public SPFilterPrimitive { - /** CONVOLVEMATRIX ATTRIBUTES HERE */ - + /* CONVOLVEMATRIX ATTRIBUTES */ + NumberOptNumber order; + std::vector kernelMatrix; + double divisor, bias; + int targetX, targetY; + unsigned short edgeMode; + NumberOptNumber kernelUnitLength; + bool preserveAlpha; }; struct SPFeConvolveMatrixClass { -- 2.30.2