From 0cc082e09c2ce5f515a90ce45a6a440c11150dc6 Mon Sep 17 00:00:00 2001 From: JucaBlues Date: Mon, 11 Feb 2008 01:48:14 +0000 Subject: [PATCH] Offline work done during weekend: * handle fefuncR, fefuncG, fefuncB and fefuncA nodes * implement fecomponenttransfer renderer ** identity and gamma modes render perfectly ** linear and table modes are rendering with very slight imperfections This commit still mantains feComponentTransfer out of UI (still not implemented) --- src/Makefile_insert | 1 + src/display/nr-filter-component-transfer.cpp | 113 ++++-- src/display/nr-filter-component-transfer.h | 23 +- src/helper-fns.h | 10 + src/sp-fecomponenttransfer-funcnode.cpp | 344 +++++++++++++++++++ src/sp-fecomponenttransfer-funcnode.h | 72 ++++ src/sp-fecomponenttransfer.cpp | 136 +++++--- src/sp-fecomponenttransfer.h | 9 +- src/sp-object-repr.cpp | 5 + src/ui/dialog/filter-effects-dialog.cpp | 8 +- 10 files changed, 609 insertions(+), 112 deletions(-) create mode 100644 src/sp-fecomponenttransfer-funcnode.cpp create mode 100644 src/sp-fecomponenttransfer-funcnode.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 196d5e562..d37cb9b59 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -165,6 +165,7 @@ libinkpre_a_SOURCES = \ sp-fecolormatrix.cpp sp-fecolormatrix.h \ sp-fecolormatrix-fns.h \ sp-fecomponenttransfer.cpp sp-fecomponenttransfer.h \ + sp-fecomponenttransfer-funcnode.cpp sp-fecomponenttransfer-funcnode.h \ sp-fecomponenttransfer-fns.h \ sp-fecomposite.cpp sp-fecomposite.h \ sp-fecomposite-fns.h \ diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index 9b2003402..1edb3ac98 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -11,12 +11,15 @@ #include "display/nr-filter-component-transfer.h" #include "display/nr-filter-units.h" +#include "display/nr-filter-utils.h" +#include "libnr/nr-pixblock.h" +#include "libnr/nr-blit.h" +#include namespace NR { FilterComponentTransfer::FilterComponentTransfer() { - g_warning("FilterComponentTransfer::render not implemented."); } FilterPrimitive * FilterComponentTransfer::create() { @@ -28,25 +31,92 @@ FilterComponentTransfer::~FilterComponentTransfer() int FilterComponentTransfer::render(FilterSlot &slot, FilterUnits const &/*units*/) { NRPixBlock *in = slot.get(_input); + if (!in) { g_warning("Missing source image for feComponentTransfer (in=%d)", _input); return 1; } - NRPixBlock *out = new NRPixBlock; + int x0=in->area.x0; + int x1=in->area.x1; + int y0=in->area.y0; + int y1=in->area.y1; - nr_pixblock_setup_fast(out, in->mode, - in->area.x0, in->area.y0, in->area.x1, in->area.y1, - true); + NRPixBlock *out = new NRPixBlock; + nr_pixblock_setup_fast(out, NR_PIXBLOCK_MODE_R8G8B8A8N, x0, y0, x1, y1, true); + + // this primitive is defined for non-premultiplied RGBA values, + // thus convert them to that format before blending + if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) { + NRPixBlock *original_in = in; + in = new NRPixBlock; + nr_pixblock_setup_fast(in, NR_PIXBLOCK_MODE_R8G8B8A8N, + original_in->area.x0, original_in->area.y0, + original_in->area.x1, original_in->area.y1, + false); + nr_blit_pixblock_pixblock(in, original_in); + } unsigned char *in_data = NR_PIXBLOCK_PX(in); unsigned char *out_data = NR_PIXBLOCK_PX(out); -//IMPLEMENT ME! - g_warning("Renderer for feComponentTransfer is not implemented."); (void)in_data; (void)out_data; + int size = 4 * (y1-y0) * (x1-x0); + int i; + + for (int color=0;color<4;color++){ + int _vsize = tableValues[color].size(); + std::vector _tableValues = tableValues[color]; + double _intercept = intercept[color]; + double _slope = slope[color]; + double _amplitude = amplitude[color]; + double _exponent = exponent[color]; + double _offset = offset[color]; + switch(type[color]){ + case COMPONENTTRANSFER_TYPE_IDENTITY: + for(i=color;iempty = FALSE; slot.set(_output, out); return 0; @@ -56,35 +126,6 @@ void FilterComponentTransfer::area_enlarge(NRRectL &/*area*/, Matrix const &/*tr { } -void FilterComponentTransfer::set_type(FilterComponentTransferType t){ - type = t; -} - -void FilterComponentTransfer::set_slope(double s){ - slope = s; -} - -void FilterComponentTransfer::set_tableValues(std::vector &tv){ - tableValues = tv; -} - - -void FilterComponentTransfer::set_intercept(double i){ - intercept = i; -} - -void FilterComponentTransfer::set_amplitude(double a){ - amplitude = a; -} - -void FilterComponentTransfer::set_exponent(double e){ - exponent = e; -} - -void FilterComponentTransfer::set_offset(double o){ - offset = o; -} - } /* namespace NR */ /* diff --git a/src/display/nr-filter-component-transfer.h b/src/display/nr-filter-component-transfer.h index 30b793777..ae08d6f29 100644 --- a/src/display/nr-filter-component-transfer.h +++ b/src/display/nr-filter-component-transfer.h @@ -37,22 +37,13 @@ public: virtual int render(FilterSlot &slot, FilterUnits const &units); virtual void area_enlarge(NRRectL &area, Matrix const &trans); - void set_type(FilterComponentTransferType t); - void set_tableValues(std::vector& tv); - void set_slope(double s); - void set_intercept(double i); - void set_amplitude(double a); - void set_exponent(double e); - void set_offset(double o); - -private: - FilterComponentTransferType type; - std::vector tableValues; - double slope; - double intercept; - double amplitude; - double exponent; - double offset; + FilterComponentTransferType type[4]; + std::vector tableValues[4]; + double slope[4]; + double intercept[4]; + double amplitude[4]; + double exponent[4]; + double offset[4]; }; } /* namespace NR */ diff --git a/src/helper-fns.h b/src/helper-fns.h index b1a1e37f0..635aefd79 100644 --- a/src/helper-fns.h +++ b/src/helper-fns.h @@ -61,6 +61,16 @@ inline std::vector helperfns_read_vector(const gchar* value, int size){ return v; } +inline std::vector helperfns_read_vector(const gchar* value){ + std::vector v; + std::istringstream is(value); + gdouble d; + while (is >> d){ + v.push_back(d); + } + return v; +} + #endif /* !SEEN_HELPER_FNS_H */ /* diff --git a/src/sp-fecomponenttransfer-funcnode.cpp b/src/sp-fecomponenttransfer-funcnode.cpp new file mode 100644 index 000000000..84f71970c --- /dev/null +++ b/src/sp-fecomponenttransfer-funcnode.cpp @@ -0,0 +1,344 @@ +#define __SP_FEFUNCNODE_CPP__ + +/** \file + * SVG , , and implementations. + */ +/* + * Authors: + * Hugo Rodrigues + * Niko Kiirala + * Felipe Corrêa da Silva Sanches + * + * Copyright (C) 2006, 2007, 2008 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "attributes.h" +#include "document.h" +#include "sp-fecomponenttransfer.h" +#include "sp-fecomponenttransfer-funcnode.h" +#include "display/nr-filter-component-transfer.h" +#include "xml/repr.h" +#include "helper-fns.h" + +#define SP_MACROS_SILENT +#include "macros.h" + +/* FeFuncNode class */ + +static void sp_fefuncnode_class_init(SPFeFuncNodeClass *klass); +static void sp_fefuncnode_init(SPFeFuncNode *fefuncnode); + +static void sp_fefuncnode_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_fefuncnode_release(SPObject *object); +static void sp_fefuncnode_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_fefuncnode_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_fefuncnode_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *feFuncNode_parent_class; + +GType +sp_fefuncR_get_type() +{ + static GType fefuncnode_type = 0; + + if (!fefuncnode_type) { + GTypeInfo fefuncnode_info = { + sizeof(SPFeFuncNodeClass), + NULL, NULL, + (GClassInitFunc) sp_fefuncnode_class_init, + NULL, NULL, + sizeof(SPFeFuncNode), + 16, + (GInstanceInitFunc) sp_fefuncnode_init, + NULL, /* value_table */ + }; + fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncR", &fefuncnode_info, (GTypeFlags)0); + } + return fefuncnode_type; +} + +GType +sp_fefuncG_get_type() +{ + static GType fefuncnode_type = 0; + + if (!fefuncnode_type) { + GTypeInfo fefuncnode_info = { + sizeof(SPFeFuncNodeClass), + NULL, NULL, + (GClassInitFunc) sp_fefuncnode_class_init, + NULL, NULL, + sizeof(SPFeFuncNode), + 16, + (GInstanceInitFunc) sp_fefuncnode_init, + NULL, /* value_table */ + }; + fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncG", &fefuncnode_info, (GTypeFlags)0); + } + return fefuncnode_type; +} + +GType +sp_fefuncB_get_type() +{ + static GType fefuncnode_type = 0; + + if (!fefuncnode_type) { + GTypeInfo fefuncnode_info = { + sizeof(SPFeFuncNodeClass), + NULL, NULL, + (GClassInitFunc) sp_fefuncnode_class_init, + NULL, NULL, + sizeof(SPFeFuncNode), + 16, + (GInstanceInitFunc) sp_fefuncnode_init, + NULL, /* value_table */ + }; + fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncB", &fefuncnode_info, (GTypeFlags)0); + } + return fefuncnode_type; +} + +GType +sp_fefuncA_get_type() +{ + static GType fefuncnode_type = 0; + + if (!fefuncnode_type) { + GTypeInfo fefuncnode_info = { + sizeof(SPFeFuncNodeClass), + NULL, NULL, + (GClassInitFunc) sp_fefuncnode_class_init, + NULL, NULL, + sizeof(SPFeFuncNode), + 16, + (GInstanceInitFunc) sp_fefuncnode_init, + NULL, /* value_table */ + }; + fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncA", &fefuncnode_info, (GTypeFlags)0); + } + return fefuncnode_type; +} + +static void +sp_fefuncnode_class_init(SPFeFuncNodeClass *klass) +{ + + SPObjectClass *sp_object_class = (SPObjectClass *)klass; + + feFuncNode_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_fefuncnode_build; + sp_object_class->release = sp_fefuncnode_release; + sp_object_class->write = sp_fefuncnode_write; + sp_object_class->set = sp_fefuncnode_set; + sp_object_class->update = sp_fefuncnode_update; +} + +static void +sp_fefuncnode_init(SPFeFuncNode *fefuncnode) +{ + fefuncnode->type = NR::COMPONENTTRANSFER_TYPE_IDENTITY; + //fefuncnode->tableValues = NULL; + fefuncnode->slope = 1; + fefuncnode->intercept = 0; + fefuncnode->amplitude = 1; + fefuncnode->exponent = 1; + fefuncnode->offset = 0; +} + +/** + * Reads the Inkscape::XML::Node, and initializes SPDistantLight variables. For this to get called, + * our name must be associated with a repr via "sp_object_type_register". Best done through + * sp-object-repr.cpp's repr_name_entries array. + */ +static void +sp_fefuncnode_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) feFuncNode_parent_class)->build) { + ((SPObjectClass *) feFuncNode_parent_class)->build(object, document, repr); + } + + //Read values of key attributes from XML nodes into object. + sp_object_read_attr(object, "type"); + sp_object_read_attr(object, "tableValues"); + sp_object_read_attr(object, "slope"); + sp_object_read_attr(object, "intercept"); + sp_object_read_attr(object, "amplitude"); + sp_object_read_attr(object, "exponent"); + sp_object_read_attr(object, "offset"); + + +//is this necessary? + sp_document_add_resource(document, "fefuncnode", object); //maybe feFuncR, fefuncG, feFuncB and fefuncA ? +} + +/** + * Drops any allocated memory. + */ +static void +sp_fefuncnode_release(SPObject *object) +{ + //SPFeFuncNode *fefuncnode = SP_FEFUNCNODE(object); + + if (SP_OBJECT_DOCUMENT(object)) { + /* Unregister ourselves */ + sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "fefuncnode", SP_OBJECT(object)); + } + +//TODO: release resources here +} + +static NR::FilterComponentTransferType sp_feComponenttransfer_read_type(gchar const *value){ + if (!value) return NR::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED. + switch(value[0]){ + case 'i': + if (strncmp(value, "identity", 8) == 0) return NR::COMPONENTTRANSFER_TYPE_IDENTITY; + break; + case 't': + if (strncmp(value, "table", 5) == 0) return NR::COMPONENTTRANSFER_TYPE_TABLE; + break; + case 'd': + if (strncmp(value, "discrete", 8) == 0) return NR::COMPONENTTRANSFER_TYPE_DISCRETE; + break; + case 'l': + if (strncmp(value, "linear", 6) == 0) return NR::COMPONENTTRANSFER_TYPE_LINEAR; + break; + case 'g': + if (strncmp(value, "gamma", 5) == 0) return NR::COMPONENTTRANSFER_TYPE_GAMMA; + break; + } + return NR::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED. +} + +/** + * Sets a specific value in the SPFeFuncNode. + */ +static void +sp_fefuncnode_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPFeFuncNode *feFuncNode = SP_FEFUNCNODE(object); + NR::FilterComponentTransferType type; + double read_num; + switch(key) { + case SP_ATTR_TYPE: + type = sp_feComponenttransfer_read_type(value); + if(type != feFuncNode->type) { + feFuncNode->type = type; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_TABLEVALUES: + if (value){ + feFuncNode->tableValues = helperfns_read_vector(value); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_SLOPE: + read_num = helperfns_read_number(value); + if (read_num != feFuncNode->slope) { + feFuncNode->slope = read_num; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_INTERCEPT: + read_num = helperfns_read_number(value); + if (read_num != feFuncNode->intercept) { + feFuncNode->intercept = read_num; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_AMPLITUDE: + read_num = helperfns_read_number(value); + if (read_num != feFuncNode->amplitude) { + feFuncNode->amplitude = read_num; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_EXPONENT: + read_num = helperfns_read_number(value); + if (read_num != feFuncNode->exponent) { + feFuncNode->exponent = read_num; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_OFFSET: + read_num = helperfns_read_number(value); + if (read_num != feFuncNode->offset) { + feFuncNode->offset = read_num; + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + default: + if (((SPObjectClass *) feFuncNode_parent_class)->set) + ((SPObjectClass *) feFuncNode_parent_class)->set(object, key, value); + break; + } +} + +/** + * * Receives update notifications. + * */ +static void +sp_fefuncnode_update(SPObject *object, SPCtx *ctx, guint flags) +{ + SPFeFuncNode *feFuncNode = SP_FEFUNCNODE(object); + (void)feFuncNode; + + if (flags & SP_OBJECT_MODIFIED_FLAG) { + /* do something to trigger redisplay, updates? */ + //TODO + //sp_object_read_attr(object, "azimuth"); + //sp_object_read_attr(object, "elevation"); + } + + if (((SPObjectClass *) feFuncNode_parent_class)->update) { + ((SPObjectClass *) feFuncNode_parent_class)->update(object, ctx, flags); + } +} + +/** + * Writes its settings to an incoming repr object, if any. + */ +static Inkscape::XML::Node * +sp_fefuncnode_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPFeFuncNode *fefuncnode = SP_FEFUNCNODE(object); + + if (!repr) { + repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME + } + + /* +TODO: I'm not sure what to do here... + + if (fefuncnode->azimuth_set) + sp_repr_set_css_double(repr, "azimuth", fefuncnode->azimuth); + if (fefuncnode->elevation_set) + sp_repr_set_css_double(repr, "elevation", fefuncnode->elevation);*/ + + if (((SPObjectClass *) feFuncNode_parent_class)->write) { + ((SPObjectClass *) feFuncNode_parent_class)->write(object, repr, flags); + } + + return repr; +} + +/* + 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-fecomponenttransfer-funcnode.h b/src/sp-fecomponenttransfer-funcnode.h new file mode 100644 index 000000000..2f0b2fc28 --- /dev/null +++ b/src/sp-fecomponenttransfer-funcnode.h @@ -0,0 +1,72 @@ +#ifndef SP_FECOMPONENTTRANSFER_FUNCNODE_H_SEEN +#define SP_FECOMPONENTTRANSFER_FUNCNODE_H_SEEN + +/** \file + * SVG implementation, see sp-filter.cpp. + */ +/* + * Authors: + * Hugo Rodrigues + * Niko Kiirala + * Felipe Corrêa da Silva Sanches + * + * Copyright (C) 2006,2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" +#include "display/nr-filter-component-transfer.h" + +#define SP_TYPE_FEFUNCR (sp_fefuncR_get_type()) +#define SP_TYPE_FEFUNCG (sp_fefuncG_get_type()) +#define SP_TYPE_FEFUNCB (sp_fefuncB_get_type()) +#define SP_TYPE_FEFUNCA (sp_fefuncA_get_type()) + +#define SP_IS_FEFUNCR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCR)) +#define SP_IS_FEFUNCG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCG)) +#define SP_IS_FEFUNCB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCB)) +#define SP_IS_FEFUNCA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFUNCA)) + +#define SP_FEFUNCNODE(obj) (SP_IS_FEFUNCR(obj) ? G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEFUNCR, SPFeFuncNode) : (SP_IS_FEFUNCG(obj) ? G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEFUNCG, SPFeFuncNode) : (SP_IS_FEFUNCB(obj) ? G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEFUNCB, SPFeFuncNode):(SP_IS_FEFUNCA(obj) ? G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_FEFUNCA, SPFeFuncNode): NULL)))) + +#define SP_FEFUNCNODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_FEFUNCNODE, SPFeFuncNodeClass)) + +#define SP_IS_FEFUNCNODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEFUNCNODE)) + +/* Component Transfer funcNode class */ + +class SPFeFuncNode; +class SPFeFuncNodeClass; + +struct SPFeFuncNode : public SPObject { + NR::FilterComponentTransferType type; + std::vector tableValues; + double slope; + double intercept; + double amplitude; + double exponent; + double offset; +}; + +struct SPFeFuncNodeClass { + SPObjectClass parent_class; +}; + +GType sp_fefuncR_get_type(); +GType sp_fefuncG_get_type(); +GType sp_fefuncB_get_type(); +GType sp_fefuncA_get_type(); + +#endif /* !SP_FECOMPONENTTRANSFER_FUNCNODE_H_SEEN */ + +/* + 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-fecomponenttransfer.cpp b/src/sp-fecomponenttransfer.cpp index f9ecaa47c..0b0054639 100644 --- a/src/sp-fecomponenttransfer.cpp +++ b/src/sp-fecomponenttransfer.cpp @@ -19,11 +19,13 @@ #include +#include "document.h" #include "attributes.h" #include "svg/svg.h" #include "sp-fecomponenttransfer.h" +#include "sp-fecomponenttransfer-funcnode.h" #include "xml/repr.h" -#include "display/nr-filter-component-transfer.h" +//#include "display/nr-filter-component-transfer.h" /* FeComponentTransfer base class */ @@ -34,8 +36,10 @@ static void sp_feComponentTransfer_build(SPObject *object, SPDocument *document, static void sp_feComponentTransfer_release(SPObject *object); static void sp_feComponentTransfer_set(SPObject *object, unsigned int key, gchar const *value); static void sp_feComponentTransfer_update(SPObject *object, SPCtx *ctx, guint flags); +static void sp_feComponentTransfer_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter); +static void sp_feComponentTransfer_remove_child(SPObject *object, Inkscape::XML::Node *child); +static void sp_feComponentTransfer_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); static Inkscape::XML::Node *sp_feComponentTransfer_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); - static SPFilterPrimitiveClass *feComponentTransfer_parent_class; GType @@ -63,7 +67,7 @@ static void sp_feComponentTransfer_class_init(SPFeComponentTransferClass *klass) { SPObjectClass *sp_object_class = (SPObjectClass *)klass; - + SPFilterPrimitiveClass *sp_primitive_class = (SPFilterPrimitiveClass *)klass; feComponentTransfer_parent_class = (SPFilterPrimitiveClass*)g_type_class_peek_parent(klass); sp_object_class->build = sp_feComponentTransfer_build; @@ -71,20 +75,15 @@ sp_feComponentTransfer_class_init(SPFeComponentTransferClass *klass) sp_object_class->write = sp_feComponentTransfer_write; sp_object_class->set = sp_feComponentTransfer_set; sp_object_class->update = sp_feComponentTransfer_update; + sp_object_class->child_added = sp_feComponentTransfer_child_added; + sp_object_class->remove_child = sp_feComponentTransfer_remove_child; + + sp_primitive_class->build_renderer = sp_feComponentTransfer_build_renderer; } static void sp_feComponentTransfer_init(SPFeComponentTransfer *feComponentTransfer) -{ - //Setting default values: -//TODO: tableValues = "" (empty list); - feComponentTransfer->slope = 1; - feComponentTransfer->intercept = 0; - feComponentTransfer->amplitude = 1; - feComponentTransfer->exponent = 1; - feComponentTransfer->offset = 0; -// feComponentTransfer->type = NR::COMPONENTTRANSFER_TYPE_ERROR; -} +{} /** * Reads the Inkscape::XML::Node, and initializes SPFeComponentTransfer variables. For this to get called, @@ -99,13 +98,63 @@ sp_feComponentTransfer_build(SPObject *object, SPDocument *document, Inkscape::X } /*LOAD ATTRIBUTES FROM REPR HERE*/ - sp_object_read_attr(object, "type"); - sp_object_read_attr(object, "tableValues"); - sp_object_read_attr(object, "slope"); - sp_object_read_attr(object, "intercept"); - sp_object_read_attr(object, "amplitude"); - sp_object_read_attr(object, "exponent"); - sp_object_read_attr(object, "offset"); + + //do we need this? + sp_document_add_resource(document, "feComponentTransfer", object); +} + +static void sp_feComponentTransfer_children_modified(SPFeComponentTransfer *sp_componenttransfer) +{ + if (sp_componenttransfer->renderer) { + SPObject* node = sp_componenttransfer->children; + for(;node;node=node->next){ + int i=4; + if (SP_IS_FEFUNCR(node)) i=0; + if (SP_IS_FEFUNCG(node)) i=1; + if (SP_IS_FEFUNCB(node)) i=2; + if (SP_IS_FEFUNCA(node)) i=3; + if (i==4) break; + sp_componenttransfer->renderer->type[i] = ((SPFeFuncNode *) node)->type; + sp_componenttransfer->renderer->tableValues[i] = ((SPFeFuncNode *) node)->tableValues; + sp_componenttransfer->renderer->slope[i] = ((SPFeFuncNode *) node)->slope; + sp_componenttransfer->renderer->intercept[i] = ((SPFeFuncNode *) node)->intercept; + sp_componenttransfer->renderer->amplitude[i] = ((SPFeFuncNode *) node)->amplitude; + sp_componenttransfer->renderer->exponent[i] = ((SPFeFuncNode *) node)->exponent; + sp_componenttransfer->renderer->offset[i] = ((SPFeFuncNode *) node)->offset; + } + } +} + +/** + * Callback for child_added event. + */ +static void +sp_feComponentTransfer_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + g_warning("child_added"); + SPFeComponentTransfer *f = SP_FECOMPONENTTRANSFER(object); + + if (((SPObjectClass *) feComponentTransfer_parent_class)->child_added) + (* ((SPObjectClass *) feComponentTransfer_parent_class)->child_added)(object, child, ref); + + sp_feComponentTransfer_children_modified(f); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + + +/** + * Callback for remove_child event. + */ +static void +sp_feComponentTransfer_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + SPFeComponentTransfer *f = SP_FECOMPONENTTRANSFER(object); + + if (((SPObjectClass *) feComponentTransfer_parent_class)->remove_child) + (* ((SPObjectClass *) feComponentTransfer_parent_class)->remove_child)(object, child); + + sp_feComponentTransfer_children_modified(f); + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); } /** @@ -118,28 +167,6 @@ sp_feComponentTransfer_release(SPObject *object) ((SPObjectClass *) feComponentTransfer_parent_class)->release(object); } -static NR::FilterComponentTransferType sp_feComponenttransfer_read_type(gchar const *value){ - if (!value) return NR::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED. - switch(value[0]){ - case 'i': - if (strncmp(value, "identity", 8) == 0) return NR::COMPONENTTRANSFER_TYPE_IDENTITY; - break; - case 't': - if (strncmp(value, "table", 5) == 0) return NR::COMPONENTTRANSFER_TYPE_TABLE; - break; - case 'd': - if (strncmp(value, "discrete", 8) == 0) return NR::COMPONENTTRANSFER_TYPE_DISCRETE; - break; - case 'l': - if (strncmp(value, "linear", 6) == 0) return NR::COMPONENTTRANSFER_TYPE_LINEAR; - break; - case 'g': - if (strncmp(value, "gamma", 5) == 0) return NR::COMPONENTTRANSFER_TYPE_GAMMA; - break; - } - return NR::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED. -} - /** * Sets a specific value in the SPFeComponentTransfer. */ @@ -149,15 +176,7 @@ sp_feComponentTransfer_set(SPObject *object, unsigned int key, gchar const *valu SPFeComponentTransfer *feComponentTransfer = SP_FECOMPONENTTRANSFER(object); (void)feComponentTransfer; - NR::FilterComponentTransferType type; switch(key) { - case SP_ATTR_TYPE: - type = sp_feComponenttransfer_read_type(value); - if(type != feComponentTransfer->type) { - feComponentTransfer->type = type; - object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); - } - break; /*DEAL WITH SETTING ATTRIBUTES HERE*/ default: if (((SPObjectClass *) feComponentTransfer_parent_class)->set) @@ -208,6 +227,23 @@ sp_feComponentTransfer_write(SPObject *object, Inkscape::XML::Node *repr, guint return repr; } +static void sp_feComponentTransfer_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) { + g_assert(primitive != NULL); + g_assert(filter != NULL); + + SPFeComponentTransfer *sp_componenttransfer = SP_FECOMPONENTTRANSFER(primitive); + + int primitive_n = filter->add_primitive(NR::NR_FILTER_COMPONENTTRANSFER); + NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n); + NR::FilterComponentTransfer *nr_componenttransfer = dynamic_cast(nr_primitive); + g_assert(nr_componenttransfer != NULL); + + sp_componenttransfer->renderer = nr_componenttransfer; + sp_filter_primitive_renderer_common(primitive, nr_primitive); + + + sp_feComponentTransfer_children_modified(sp_componenttransfer); //do we need it?! +} /* Local Variables: diff --git a/src/sp-fecomponenttransfer.h b/src/sp-fecomponenttransfer.h index 2a0fa01ed..f32512c7a 100644 --- a/src/sp-fecomponenttransfer.h +++ b/src/sp-fecomponenttransfer.h @@ -23,13 +23,8 @@ class SPFeComponentTransferClass; struct SPFeComponentTransfer : public SPFilterPrimitive { /** COMPONENTTRANSFER ATTRIBUTES HERE */ - NR::FilterComponentTransferType type; - std::vector tableValues; - double slope; - double intercept; - double amplitude; - double exponent; - double offset; + + NR::FilterComponentTransfer *renderer; }; struct SPFeComponentTransferClass { diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp index 5fa36d7b5..57e9ef986 100644 --- a/src/sp-object-repr.cpp +++ b/src/sp-object-repr.cpp @@ -52,6 +52,7 @@ #include "sp-feblend.h" #include "sp-fecolormatrix.h" #include "sp-fecomponenttransfer.h" +#include "sp-fecomponenttransfer-funcnode.h" #include "sp-fecomposite.h" #include "sp-feconvolvematrix.h" #include "sp-fediffuselighting.h" @@ -148,6 +149,10 @@ populate_dtables() { "svg:feDistantLight", SP_TYPE_FEDISTANTLIGHT }, { "svg:feDisplacementMap", SP_TYPE_FEDISPLACEMENTMAP }, { "svg:feFlood", SP_TYPE_FEFLOOD }, + { "svg:feFuncR", SP_TYPE_FEFUNCR }, + { "svg:feFuncG", SP_TYPE_FEFUNCG }, + { "svg:feFuncB", SP_TYPE_FEFUNCB }, + { "svg:feFuncA", SP_TYPE_FEFUNCA }, { "svg:feGaussianBlur", SP_TYPE_GAUSSIANBLUR }, { "svg:feImage", SP_TYPE_FEIMAGE }, { "svg:feMerge", SP_TYPE_FEMERGE }, diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 12cb29bef..9856c63b7 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -2345,19 +2345,21 @@ void FilterEffectsDialog::update_settings_sensitivity() _k3->set_sensitive(use_k); _k4->set_sensitive(use_k); +// Component transfer not yet implemented +/* if(SP_IS_FECOMPONENTTRANSFER(prim)) { SPFeComponentTransfer* ct = SP_FECOMPONENTTRANSFER(prim); const bool linear = ct->type == COMPONENTTRANSFER_TYPE_LINEAR; const bool gamma = ct->type == COMPONENTTRANSFER_TYPE_GAMMA; - // Component transfer not yet implemented - /*_ct_table->set_sensitive(ct->type == COMPONENTTRANSFER_TYPE_TABLE || ct->type == COMPONENTTRANSFER_TYPE_DISCRETE); + _ct_table->set_sensitive(ct->type == COMPONENTTRANSFER_TYPE_TABLE || ct->type == COMPONENTTRANSFER_TYPE_DISCRETE); _ct_slope->set_sensitive(linear); _ct_intercept->set_sensitive(linear); _ct_amplitude->set_sensitive(gamma); _ct_exponent->set_sensitive(gamma); - _ct_offset->set_sensitive(gamma);*/ + _ct_offset->set_sensitive(gamma); } +*/ } void FilterEffectsDialog::update_color_matrix() -- 2.30.2