summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e8fd2d7)
raw | patch | inline | side by side (parent: e8fd2d7)
author | JucaBlues <JucaBlues@users.sourceforge.net> | |
Mon, 11 Feb 2008 01:48:14 +0000 (01:48 +0000) | ||
committer | JucaBlues <JucaBlues@users.sourceforge.net> | |
Mon, 11 Feb 2008 01:48:14 +0000 (01:48 +0000) |
* 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)
* 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 | patch | blob | history | |
src/display/nr-filter-component-transfer.cpp | patch | blob | history | |
src/display/nr-filter-component-transfer.h | patch | blob | history | |
src/helper-fns.h | patch | blob | history | |
src/sp-fecomponenttransfer-funcnode.cpp | [new file with mode: 0644] | patch | blob |
src/sp-fecomponenttransfer-funcnode.h | [new file with mode: 0644] | patch | blob |
src/sp-fecomponenttransfer.cpp | patch | blob | history | |
src/sp-fecomponenttransfer.h | patch | blob | history | |
src/sp-object-repr.cpp | patch | blob | history | |
src/ui/dialog/filter-effects-dialog.cpp | patch | blob | history |
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 196d5e562bd9f4419219dcad524e1184e222ab8a..d37cb9b59ba0d71bd01771cd77158356bcc85f2f 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
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 9b20034022998ceabff5c74d13c0e8964b7c9c20..1edb3ac98fcca609f2bed031d64e1e4d441bc013 100644 (file)
#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 <math.h>
namespace NR {
FilterComponentTransfer::FilterComponentTransfer()
{
- g_warning("FilterComponentTransfer::render not implemented.");
}
FilterPrimitive * FilterComponentTransfer::create() {
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<gdouble> _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;i<size;i+=4){
+ out_data[i]=in_data[i];
+ }
+ break;
+ case COMPONENTTRANSFER_TYPE_TABLE:
+ if (_vsize==0){
+ for(i=color;i<size;i+=4){
+ out_data[i]=in_data[i];
+ }
+ } else {
+ for(i=color;i<size;i+=4){
+ int k = (int)(((_vsize-1) * (double)in_data[i])/256);
+ double dx = ((_vsize-1) * (double)in_data[i])/256 - k;
+ out_data[i] = CLAMP_D_TO_U8(256 * (_tableValues[k] + dx * (_tableValues[k+1] - _tableValues[k]) ));
+ }
+ }
+ break;
+ case COMPONENTTRANSFER_TYPE_DISCRETE:
+ if (_vsize==0){
+ for(i=color;i<size;i+=4){
+ out_data[i] = in_data[i];
+ }
+ } else {
+ for(i=color;i<size;i+=4){
+ out_data[i] = CLAMP_D_TO_U8(256 * _tableValues[(int)((_vsize-1)*(double)in_data[i]/256)] );
+ }
+ }
+ break;
+ case COMPONENTTRANSFER_TYPE_LINEAR:
+ for(i=color;i<size;i+=4){
+ out_data[i] = CLAMP_D_TO_U8(256 * (_slope * (double)in_data[i]/256 + _intercept));
+ }
+ break;
+ case COMPONENTTRANSFER_TYPE_GAMMA:
+ for(i=color;i<size;i+=4){
+ out_data[i] = CLAMP_D_TO_U8(256 * (_amplitude * pow((double)in_data[i]/256, _exponent) + _offset));
+ }
+ break;
+ }
+ }
+
out->empty = 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<double> &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 30b793777abf271d41d36cd4670198ae6777bdec..ae08d6f290c60e55a8f13f3622731b1389694db8 100644 (file)
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<gdouble>& 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<gdouble> tableValues;
- double slope;
- double intercept;
- double amplitude;
- double exponent;
- double offset;
+ FilterComponentTransferType type[4];
+ std::vector<gdouble> 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 b1a1e37f05f744bcf689db179165a9d33bb7627b..635aefd79525ddee3554a308ca15f5e394678191 100644 (file)
--- a/src/helper-fns.h
+++ b/src/helper-fns.h
return v;
}
+inline std::vector<gdouble> helperfns_read_vector(const gchar* value){
+ std::vector<gdouble> 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
--- /dev/null
@@ -0,0 +1,344 @@
+#define __SP_FEFUNCNODE_CPP__
+
+/** \file
+ * SVG <funcR>, <funcG>, <funcB> and <funcA> implementations.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Felipe CorrĂȘa da Silva Sanches <felipe.sanches@gmail.com>
+ *
+ * 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 <glib.h>
+
+#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
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef SP_FECOMPONENTTRANSFER_FUNCNODE_H_SEEN
+#define SP_FECOMPONENTTRANSFER_FUNCNODE_H_SEEN
+
+/** \file
+ * SVG <filter> implementation, see sp-filter.cpp.
+ */
+/*
+ * Authors:
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Niko Kiirala <niko@kiirala.com>
+ * Felipe CorrĂȘa da Silva Sanches <felipe.sanches@gmail.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-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<double> 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 :
index f9ecaa47ca87ee16d97f53839082e65ce9052497..0b00546391dc3268abf3b0b135dca059723f3a27 100644 (file)
#include <string.h>
+#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 */
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
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;
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);
}
/**
((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::FilterComponentTransfer*>(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:
index 2a0fa01ed41ae577c99e59327326cbc4839333df..f32512c7a5be6a8fd6583718bba1c4d477657a4b 100644 (file)
struct SPFeComponentTransfer : public SPFilterPrimitive {
/** COMPONENTTRANSFER ATTRIBUTES HERE */
- NR::FilterComponentTransferType type;
- std::vector<double> 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 5fa36d7b589884692431abe5fafe082ca66aab07..57e9ef986627465e5b4041bd3682777a27355270 100644 (file)
--- a/src/sp-object-repr.cpp
+++ b/src/sp-object-repr.cpp
#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"
{ "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 },
index 12cb29bef5012fe3f3341f2dcd768282dd8f4ce7..9856c63b73a208e0f7fcf2b9077cc317dc0c915b 100644 (file)
_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()