dac9b87e7d11f7cf3cb75aec066758e2ee51cca6
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;
101 }
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)
110 {
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);
127 }
129 /**
130 * Drops any allocated memory.
131 */
132 static void
133 sp_fespotlight_release(SPObject *object)
134 {
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
143 }
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)
150 {
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 }
298 }
300 /**
301 * * Receives update notifications.
302 * */
303 static void
304 sp_fespotlight_update(SPObject *object, SPCtx *ctx, guint flags)
305 {
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 }
324 }
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)
331 {
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;
360 }
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 :