Code

dac9b87e7d11f7cf3cb75aec066758e2ee51cca6
[inkscape.git] / src / filters / spotlight.cpp
1 /** \file
2  * SVG <fespotlight> implementation.
3  */
4 /*
5  * Authors:
6  *   Hugo Rodrigues <haa.rodrigues@gmail.com>
7  *   Niko Kiirala <niko@kiirala.com>
8  *   Jean-Rene Reinhard <jr@komite.net>
9  *   Abhishek Sharma
10  *
11  * Copyright (C) 2006,2007 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 "spotlight.h"
25 #include "diffuselighting-fns.h"
26 #include "specularlighting-fns.h"
27 #include "xml/repr.h"
29 #define SP_MACROS_SILENT
30 #include "macros.h"
32 /* FeSpotLight class */
34 static void sp_fespotlight_class_init(SPFeSpotLightClass *klass);
35 static void sp_fespotlight_init(SPFeSpotLight *fespotlight);
37 static void sp_fespotlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
38 static void sp_fespotlight_release(SPObject *object);
39 static void sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value);
40 static void sp_fespotlight_update(SPObject *object, SPCtx *ctx, guint flags);
41 static Inkscape::XML::Node *sp_fespotlight_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
43 static SPObjectClass *feSpotLight_parent_class;
45 GType
46 sp_fespotlight_get_type()
47 {
48     static GType fespotlight_type = 0;
50     if (!fespotlight_type) {
51         GTypeInfo fespotlight_info = {
52             sizeof(SPFeSpotLightClass),
53             NULL, NULL,
54             (GClassInitFunc) sp_fespotlight_class_init,
55             NULL, NULL,
56             sizeof(SPFeSpotLight),
57             16,
58             (GInstanceInitFunc) sp_fespotlight_init,
59             NULL,    /* value_table */
60         };
61         fespotlight_type = g_type_register_static(SP_TYPE_OBJECT, "SPFeSpotLight", &fespotlight_info, (GTypeFlags)0);
62     }
63     return fespotlight_type;
64 }
66 static void
67 sp_fespotlight_class_init(SPFeSpotLightClass *klass)
68 {
70     SPObjectClass *sp_object_class = (SPObjectClass *)klass;
72     feSpotLight_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass);
74     sp_object_class->build = sp_fespotlight_build;
75     sp_object_class->release = sp_fespotlight_release;
76     sp_object_class->write = sp_fespotlight_write;
77     sp_object_class->set = sp_fespotlight_set;
78     sp_object_class->update = sp_fespotlight_update;
79 }
81 static void
82 sp_fespotlight_init(SPFeSpotLight *fespotlight)
83 {
84     fespotlight->x = 0;
85     fespotlight->y = 0;
86     fespotlight->z = 0;
87     fespotlight->pointsAtX = 0;
88     fespotlight->pointsAtY = 0;
89     fespotlight->pointsAtZ = 0;
90     fespotlight->specularExponent = 1;
91     fespotlight->limitingConeAngle = 90;
93     fespotlight->x_set = FALSE;
94     fespotlight->y_set = FALSE;
95     fespotlight->z_set = FALSE;
96     fespotlight->pointsAtX_set = FALSE;
97     fespotlight->pointsAtY_set = FALSE;
98     fespotlight->pointsAtZ_set = FALSE;
99     fespotlight->specularExponent_set = FALSE;
100     fespotlight->limitingConeAngle_set = FALSE;
103 /**
104  * Reads the Inkscape::XML::Node, and initializes SPPointLight variables.  For this to get called,
105  * our name must be associated with a repr via "sp_object_type_register".  Best done through
106  * sp-object-repr.cpp's repr_name_entries array.
107  */
108 static void
109 sp_fespotlight_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
111     if (((SPObjectClass *) feSpotLight_parent_class)->build) {
112         ((SPObjectClass *) feSpotLight_parent_class)->build(object, document, repr);
113     }
115     //Read values of key attributes from XML nodes into object.
116     object->readAttr( "x" );
117     object->readAttr( "y" );
118     object->readAttr( "z" );
119     object->readAttr( "pointsAtX" );
120     object->readAttr( "pointsAtY" );
121     object->readAttr( "pointsAtZ" );
122     object->readAttr( "specularExponent" );
123     object->readAttr( "limitingConeAngle" );
125 //is this necessary?
126     document->addResource("fespotlight", object);
129 /**
130  * Drops any allocated memory.
131  */
132 static void
133 sp_fespotlight_release(SPObject *object)
135     //SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
137     if (SP_OBJECT_DOCUMENT(object)) {
138         /* Unregister ourselves */
139         SP_OBJECT_DOCUMENT(object)->removeResource("fespotlight", SP_OBJECT(object));
140     }
142 //TODO: release resources here
145 /**
146  * Sets a specific value in the SPFeSpotLight.
147  */
148 static void
149 sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
151     SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
152     gchar *end_ptr;
154     switch (key) {
155     case SP_ATTR_X:
156         end_ptr = NULL;
157         if (value) {
158             fespotlight->x = g_ascii_strtod(value, &end_ptr);
159             if (end_ptr)
160                 fespotlight->x_set = TRUE;
161         }
162         if(!value || !end_ptr) {
163             fespotlight->x = 0;
164             fespotlight->x_set = FALSE;
165         }
166         if (object->parent &&
167                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
168                  SP_IS_FESPECULARLIGHTING(object->parent))) {
169             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
170         }
171         break;
172     case SP_ATTR_Y:
173         end_ptr = NULL;
174         if (value) {
175             fespotlight->y = g_ascii_strtod(value, &end_ptr);
176             if (end_ptr)
177                 fespotlight->y_set = TRUE;
178         }
179         if(!value || !end_ptr) {
180             fespotlight->y = 0;
181             fespotlight->y_set = FALSE;
182         }
183         if (object->parent &&
184                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
185                  SP_IS_FESPECULARLIGHTING(object->parent))) {
186             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
187         }
188         break;
189     case SP_ATTR_Z:
190         end_ptr = NULL;
191         if (value) {
192             fespotlight->z = g_ascii_strtod(value, &end_ptr);
193             if (end_ptr)
194                 fespotlight->z_set = TRUE;
195         }
196         if(!value || !end_ptr) {
197             fespotlight->z = 0;
198             fespotlight->z_set = FALSE;
199         }
200         if (object->parent &&
201                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
202                  SP_IS_FESPECULARLIGHTING(object->parent))) {
203             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
204         }
205         break;
206     case SP_ATTR_POINTSATX:
207         end_ptr = NULL;
208         if (value) {
209             fespotlight->pointsAtX = g_ascii_strtod(value, &end_ptr);
210             if (end_ptr)
211                 fespotlight->pointsAtX_set = TRUE;
212         }
213         if(!value || !end_ptr) {
214             fespotlight->pointsAtX = 0;
215             fespotlight->pointsAtX_set = FALSE;
216         }
217         if (object->parent &&
218                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
219                  SP_IS_FESPECULARLIGHTING(object->parent))) {
220             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
221         }
222         break;
223     case SP_ATTR_POINTSATY:
224         end_ptr = NULL;
225         if (value) {
226             fespotlight->pointsAtY = g_ascii_strtod(value, &end_ptr);
227             if (end_ptr)
228                 fespotlight->pointsAtY_set = TRUE;
229         }
230         if(!value || !end_ptr) {
231             fespotlight->pointsAtY = 0;
232             fespotlight->pointsAtY_set = FALSE;
233         }
234         if (object->parent &&
235                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
236                  SP_IS_FESPECULARLIGHTING(object->parent))) {
237             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
238         }
239         break;
240     case SP_ATTR_POINTSATZ:
241         end_ptr = NULL;
242         if (value) {
243             fespotlight->pointsAtZ = g_ascii_strtod(value, &end_ptr);
244             if (end_ptr)
245                 fespotlight->pointsAtZ_set = TRUE;
246         }
247         if(!value || !end_ptr) {
248             fespotlight->pointsAtZ = 0;
249             fespotlight->pointsAtZ_set = FALSE;
250         }
251         if (object->parent &&
252                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
253                  SP_IS_FESPECULARLIGHTING(object->parent))) {
254             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
255         }
256         break;
257     case SP_ATTR_SPECULAREXPONENT:
258         end_ptr = NULL;
259         if (value) {
260             fespotlight->specularExponent = g_ascii_strtod(value, &end_ptr);
261             if (end_ptr)
262                 fespotlight->specularExponent_set = TRUE;
263         }
264         if(!value || !end_ptr) {
265             fespotlight->specularExponent = 1;
266             fespotlight->specularExponent_set = FALSE;
267         }
268         if (object->parent &&
269                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
270                  SP_IS_FESPECULARLIGHTING(object->parent))) {
271             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
272         }
273         break;
274     case SP_ATTR_LIMITINGCONEANGLE:
275         end_ptr = NULL;
276         if (value) {
277             fespotlight->limitingConeAngle = g_ascii_strtod(value, &end_ptr);
278             if (end_ptr)
279                 fespotlight->limitingConeAngle_set = TRUE;
280         }
281         if(!value || !end_ptr) {
282             fespotlight->limitingConeAngle = 90;
283             fespotlight->limitingConeAngle_set = FALSE;
284         }
285         if (object->parent &&
286                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
287                  SP_IS_FESPECULARLIGHTING(object->parent))) {
288             object->parent->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
289         }
290         break;
291     default:
292         // See if any parents need this value.
293         if (((SPObjectClass *) feSpotLight_parent_class)->set) {
294             ((SPObjectClass *) feSpotLight_parent_class)->set(object, key, value);
295         }
296         break;
297     }
300 /**
301  *  * Receives update notifications.
302  *   */
303 static void
304 sp_fespotlight_update(SPObject *object, SPCtx *ctx, guint flags)
306     SPFeSpotLight *feSpotLight = SP_FESPOTLIGHT(object);
307     (void)feSpotLight;
309     if (flags & SP_OBJECT_MODIFIED_FLAG) {
310         /* do something to trigger redisplay, updates? */
311         object->readAttr( "x" );
312         object->readAttr( "y" );
313         object->readAttr( "z" );
314         object->readAttr( "pointsAtX" );
315         object->readAttr( "pointsAtY" );
316         object->readAttr( "pointsAtZ" );
317         object->readAttr( "specularExponent" );
318         object->readAttr( "limitingConeAngle" );
319     }
321     if (((SPObjectClass *) feSpotLight_parent_class)->update) {
322         ((SPObjectClass *) feSpotLight_parent_class)->update(object, ctx, flags);
323     }
326 /**
327  * Writes its settings to an incoming repr object, if any.
328  */
329 static Inkscape::XML::Node *
330 sp_fespotlight_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
332     SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
334     if (!repr) {
335         repr = SP_OBJECT_REPR(object)->duplicate(doc);
336     }
338     if (fespotlight->x_set)
339         sp_repr_set_css_double(repr, "x", fespotlight->x);
340     if (fespotlight->y_set)
341         sp_repr_set_css_double(repr, "y", fespotlight->y);
342     if (fespotlight->z_set)
343         sp_repr_set_css_double(repr, "z", fespotlight->z);
344     if (fespotlight->pointsAtX_set)
345         sp_repr_set_css_double(repr, "pointsAtX", fespotlight->pointsAtX);
346     if (fespotlight->pointsAtY_set)
347         sp_repr_set_css_double(repr, "pointsAtY", fespotlight->pointsAtY);
348     if (fespotlight->pointsAtZ_set)
349         sp_repr_set_css_double(repr, "pointsAtZ", fespotlight->pointsAtZ);
350     if (fespotlight->specularExponent_set)
351         sp_repr_set_css_double(repr, "specularExponent", fespotlight->specularExponent);
352     if (fespotlight->limitingConeAngle_set)
353         sp_repr_set_css_double(repr, "limitingConeAngle", fespotlight->limitingConeAngle);
355     if (((SPObjectClass *) feSpotLight_parent_class)->write) {
356         ((SPObjectClass *) feSpotLight_parent_class)->write(object, doc, repr, flags);
357     }
359     return repr;
362 /*
363   Local Variables:
364   mode:c++
365   c-file-style:"stroustrup"
366   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
367   indent-tabs-mode:nil
368   fill-column:99
369   End:
370 */
371 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :