Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / filters / componenttransfer-funcnode.cpp
1 /** \file
2  * SVG <funcR>, <funcG>, <funcB> and <funcA> implementations.
3  */
4 /*
5  * Authors:
6  *   Hugo Rodrigues <haa.rodrigues@gmail.com>
7  *   Niko Kiirala <niko@kiirala.com>
8  *   Felipe CorrĂȘa da Silva Sanches <juca@members.fsf.org>
9  *   Abhishek Sharma
10  *
11  * Copyright (C) 2006, 2007, 2008 Authors
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #ifdef HAVE_CONFIG_H
17 # include "config.h"
18 #endif
20 #include <glib.h>
22 #include "attributes.h"
23 #include "document.h"
24 #include "componenttransfer.h"
25 #include "componenttransfer-funcnode.h"
26 #include "display/nr-filter-component-transfer.h"
27 #include "xml/repr.h"
28 #include "helper-fns.h"
30 #define SP_MACROS_SILENT
31 #include "macros.h"
33 /* FeFuncNode class */
35 static void sp_fefuncnode_class_init(SPFeFuncNodeClass *klass);
36 static void sp_fefuncnode_init(SPFeFuncNode *fefuncnode);
38 static void sp_fefuncnode_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
39 static void sp_fefuncnode_release(SPObject *object);
40 static void sp_fefuncnode_set(SPObject *object, unsigned int key, gchar const *value);
41 static void sp_fefuncnode_update(SPObject *object, SPCtx *ctx, guint flags);
42 static Inkscape::XML::Node *sp_fefuncnode_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
44 static SPObjectClass *feFuncNode_parent_class;
46 GType
47 sp_fefuncR_get_type()
48 {
49     static GType fefuncnode_type = 0;
51     if (!fefuncnode_type) {
52         GTypeInfo fefuncnode_info = {
53             sizeof(SPFeFuncNodeClass),
54             NULL, NULL,
55             (GClassInitFunc) sp_fefuncnode_class_init,
56             NULL, NULL,
57             sizeof(SPFeFuncNode),
58             16,
59             (GInstanceInitFunc) sp_fefuncnode_init,
60             NULL,    /* value_table */
61         };
62         fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncR", &fefuncnode_info, (GTypeFlags)0);
63     }
64     return fefuncnode_type;
65 }
67 GType
68 sp_fefuncG_get_type()
69 {
70     static GType fefuncnode_type = 0;
72     if (!fefuncnode_type) {
73         GTypeInfo fefuncnode_info = {
74             sizeof(SPFeFuncNodeClass),
75             NULL, NULL,
76             (GClassInitFunc) sp_fefuncnode_class_init,
77             NULL, NULL,
78             sizeof(SPFeFuncNode),
79             16,
80             (GInstanceInitFunc) sp_fefuncnode_init,
81             NULL,    /* value_table */
82         };
83         fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncG", &fefuncnode_info, (GTypeFlags)0);
84     }
85     return fefuncnode_type;
86 }
88 GType
89 sp_fefuncB_get_type()
90 {
91     static GType fefuncnode_type = 0;
93     if (!fefuncnode_type) {
94         GTypeInfo fefuncnode_info = {
95             sizeof(SPFeFuncNodeClass),
96             NULL, NULL,
97             (GClassInitFunc) sp_fefuncnode_class_init,
98             NULL, NULL,
99             sizeof(SPFeFuncNode),
100             16,
101             (GInstanceInitFunc) sp_fefuncnode_init,
102             NULL,    /* value_table */
103         };
104         fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncB", &fefuncnode_info, (GTypeFlags)0);
105     }
106     return fefuncnode_type;
109 GType
110 sp_fefuncA_get_type()
112     static GType fefuncnode_type = 0;
114     if (!fefuncnode_type) {
115         GTypeInfo fefuncnode_info = {
116             sizeof(SPFeFuncNodeClass),
117             NULL, NULL,
118             (GClassInitFunc) sp_fefuncnode_class_init,
119             NULL, NULL,
120             sizeof(SPFeFuncNode),
121             16,
122             (GInstanceInitFunc) sp_fefuncnode_init,
123             NULL,    /* value_table */
124         };
125         fefuncnode_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeFuncA", &fefuncnode_info, (GTypeFlags)0);
126     }
127     return fefuncnode_type;
130 static void
131 sp_fefuncnode_class_init(SPFeFuncNodeClass *klass)
134     SPObjectClass *sp_object_class = (SPObjectClass *)klass;
136     feFuncNode_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
138     sp_object_class->build = sp_fefuncnode_build;
139     sp_object_class->release = sp_fefuncnode_release;
140     sp_object_class->write = sp_fefuncnode_write;
141     sp_object_class->set = sp_fefuncnode_set;
142     sp_object_class->update = sp_fefuncnode_update;
145 static void
146 sp_fefuncnode_init(SPFeFuncNode *fefuncnode)
148     fefuncnode->type = Inkscape::Filters::COMPONENTTRANSFER_TYPE_IDENTITY;
149     //fefuncnode->tableValues = NULL;
150     fefuncnode->slope = 1;
151     fefuncnode->intercept = 0;
152     fefuncnode->amplitude = 1;
153     fefuncnode->exponent = 1;
154     fefuncnode->offset = 0;
157 /**
158  * Reads the Inkscape::XML::Node, and initializes SPDistantLight variables.  For this to get called,
159  * our name must be associated with a repr via "sp_object_type_register".  Best done through
160  * sp-object-repr.cpp's repr_name_entries array.
161  */
162 static void
163 sp_fefuncnode_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
165     if (((SPObjectClass *) feFuncNode_parent_class)->build) {
166         ((SPObjectClass *) feFuncNode_parent_class)->build(object, document, repr);
167     }
169     //Read values of key attributes from XML nodes into object.
170     object->readAttr( "type" );
171     object->readAttr( "tableValues" );
172     object->readAttr( "slope" );
173     object->readAttr( "intercept" );
174     object->readAttr( "amplitude" );
175     object->readAttr( "exponent" );
176     object->readAttr( "offset" );
179 //is this necessary?
180     document->addResource("fefuncnode", object); //maybe feFuncR, fefuncG, feFuncB and fefuncA ?
183 /**
184  * Drops any allocated memory.
185  */
186 static void
187 sp_fefuncnode_release(SPObject *object)
189     //SPFeFuncNode *fefuncnode = SP_FEFUNCNODE(object);
191     if (SP_OBJECT_DOCUMENT(object)) {
192         /* Unregister ourselves */
193         SP_OBJECT_DOCUMENT(object)->removeResource("fefuncnode", SP_OBJECT(object));
194     }
196 //TODO: release resources here
199 static Inkscape::Filters::FilterComponentTransferType sp_feComponenttransfer_read_type(gchar const *value){
200     if (!value) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED.
201     switch(value[0]){
202         case 'i':
203             if (strncmp(value, "identity", 8) == 0) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_IDENTITY;
204             break;
205         case 't':
206             if (strncmp(value, "table", 5) == 0) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_TABLE;
207             break;
208         case 'd':
209             if (strncmp(value, "discrete", 8) == 0) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_DISCRETE;
210             break;
211         case 'l':
212             if (strncmp(value, "linear", 6) == 0) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_LINEAR;
213             break;
214         case 'g':
215             if (strncmp(value, "gamma", 5) == 0) return Inkscape::Filters::COMPONENTTRANSFER_TYPE_GAMMA;
216             break;
217     }
218     return Inkscape::Filters::COMPONENTTRANSFER_TYPE_ERROR; //type attribute is REQUIRED.
221 /**
222  * Sets a specific value in the SPFeFuncNode.
223  */
224 static void
225 sp_fefuncnode_set(SPObject *object, unsigned int key, gchar const *value)
227     SPFeFuncNode *feFuncNode = SP_FEFUNCNODE(object);
228     Inkscape::Filters::FilterComponentTransferType type;
229     double read_num;
230     switch(key) {
231         case SP_ATTR_TYPE:
232             type = sp_feComponenttransfer_read_type(value);
233             if(type != feFuncNode->type) {
234                 feFuncNode->type = type;
235                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
236             }
237             break;
238         case SP_ATTR_TABLEVALUES:
239             if (value){
240                 feFuncNode->tableValues = helperfns_read_vector(value);
241                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
242             }
243             break;
244         case SP_ATTR_SLOPE:
245             read_num = value ? helperfns_read_number(value) : 1;
246             if (read_num != feFuncNode->slope) {
247                 feFuncNode->slope = read_num;
248                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
249             }
250             break;
251         case SP_ATTR_INTERCEPT:
252             read_num = value ? helperfns_read_number(value) : 0;
253             if (read_num != feFuncNode->intercept) {
254                 feFuncNode->intercept = read_num;
255                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
256             }
257             break;
258         case SP_ATTR_AMPLITUDE:
259             read_num = value ? helperfns_read_number(value) : 1;
260             if (read_num != feFuncNode->amplitude) {
261                 feFuncNode->amplitude = read_num;
262                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
263             }
264             break;
265         case SP_ATTR_EXPONENT:
266             read_num = value ? helperfns_read_number(value) : 1;
267             if (read_num != feFuncNode->exponent) {
268                 feFuncNode->exponent = read_num;
269                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
270             }
271             break;
272         case SP_ATTR_OFFSET:
273             read_num = value ? helperfns_read_number(value) : 0;
274             if (read_num != feFuncNode->offset) {
275                 feFuncNode->offset = read_num;
276                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
277             }
278             break;
279         default:
280             if (((SPObjectClass *) feFuncNode_parent_class)->set)
281                 ((SPObjectClass *) feFuncNode_parent_class)->set(object, key, value);
282             break;
283     }
286 /**
287  *  * Receives update notifications.
288  *   */
289 static void
290 sp_fefuncnode_update(SPObject *object, SPCtx *ctx, guint flags)
292     SPFeFuncNode *feFuncNode = SP_FEFUNCNODE(object);
293     (void)feFuncNode;
295     if (flags & SP_OBJECT_MODIFIED_FLAG) {
296         /* do something to trigger redisplay, updates? */
297         //TODO
298         //object->readAttr( "azimuth" );
299         //object->readAttr( "elevation" );
300     }
302     if (((SPObjectClass *) feFuncNode_parent_class)->update) {
303         ((SPObjectClass *) feFuncNode_parent_class)->update(object, ctx, flags);
304     }
307 /**
308  * Writes its settings to an incoming repr object, if any.
309  */
310 static Inkscape::XML::Node *
311 sp_fefuncnode_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
313     SPFeFuncNode *fefuncnode = SP_FEFUNCNODE(object);
315     if (!repr) {
316         repr = SP_OBJECT_REPR(object)->duplicate(doc);
317     }
319     (void)fefuncnode;
320     /*
321 TODO: I'm not sure what to do here...
323     if (fefuncnode->azimuth_set)
324         sp_repr_set_css_double(repr, "azimuth", fefuncnode->azimuth);
325     if (fefuncnode->elevation_set)
326         sp_repr_set_css_double(repr, "elevation", fefuncnode->elevation);*/
328     if (((SPObjectClass *) feFuncNode_parent_class)->write) {
329         ((SPObjectClass *) feFuncNode_parent_class)->write(object, doc, repr, flags);
330     }
332     return repr;
335 /*
336   Local Variables:
337   mode:c++
338   c-file-style:"stroustrup"
339   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
340   indent-tabs-mode:nil
341   fill-column:99
342   End:
343 */
344 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :