Code

Improved svg input and output for lighting effects and lights
authorjrreinhard <jrreinhard@users.sourceforge.net>
Thu, 26 Jul 2007 19:05:15 +0000 (19:05 +0000)
committerjrreinhard <jrreinhard@users.sourceforge.net>
Thu, 26 Jul 2007 19:05:15 +0000 (19:05 +0000)
src/sp-fediffuselighting.cpp
src/sp-fediffuselighting.h
src/sp-fedistantlight.cpp
src/sp-fedistantlight.h
src/sp-fepointlight.cpp
src/sp-fepointlight.h
src/sp-fespecularlighting.cpp
src/sp-fespecularlighting.h
src/sp-fespotlight.cpp
src/sp-fespotlight.h

index 543c16e8b03834536dabee69118a449baaefad58..cdb771cd021375fd158e54dc11ef34637e74ab97 100644 (file)
@@ -99,6 +99,10 @@ sp_feDiffuseLighting_init(SPFeDiffuseLighting *feDiffuseLighting)
     feDiffuseLighting->lighting_color = 0xffffffff;
     //TODO kernelUnit
     feDiffuseLighting->renderer = NULL;
+
+    feDiffuseLighting->surfaceScale_set = FALSE;
+    feDiffuseLighting->diffuseConstant_set = FALSE;
+    feDiffuseLighting->lighting_color_set = FALSE;
 }
 
 /**
@@ -138,22 +142,47 @@ static void
 sp_feDiffuseLighting_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPFeDiffuseLighting *feDiffuseLighting = SP_FEDIFFUSELIGHTING(object);
+    gchar const *cend_ptr = NULL;
+    gchar *end_ptr = NULL;
     
     switch(key) {
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
 //TODO test forbidden values
         case SP_ATTR_SURFACESCALE:
-            feDiffuseLighting->surfaceScale = g_ascii_strtod(value, NULL);
+            end_ptr = NULL;
+            if (value) {
+                feDiffuseLighting->surfaceScale = g_ascii_strtod(value, &end_ptr);
+                if (end_ptr) {
+                    feDiffuseLighting->surfaceScale_set = TRUE;
+                }
+            } 
+            if (!value || !end_ptr) {
+                feDiffuseLighting->surfaceScale = 1;
+                feDiffuseLighting->surfaceScale_set = FALSE;
+            }
             if (feDiffuseLighting->renderer) {
                 feDiffuseLighting->renderer->surfaceScale = feDiffuseLighting->surfaceScale;
             }
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_ATTR_DIFFUSECONSTANT:
-            feDiffuseLighting->diffuseConstant = g_ascii_strtod(value, NULL);
+            end_ptr = NULL;
+            if (value) {
+                feDiffuseLighting->diffuseConstant = g_ascii_strtod(value, &end_ptr);
+                if (end_ptr && feDiffuseLighting->diffuseConstant >= 0) {
+                    feDiffuseLighting->diffuseConstant_set = TRUE;
+                } else {
+                    end_ptr = NULL;
+                    g_warning("feDiffuseLighting: diffuseConstant should be a positive number ... defaulting to 1");
+                }
+            } 
+            if (!value || !end_ptr) {
+                feDiffuseLighting->diffuseConstant = 1;
+                feDiffuseLighting->diffuseConstant_set = FALSE;
+            }
             if (feDiffuseLighting->renderer) {
                 feDiffuseLighting->renderer->diffuseConstant = feDiffuseLighting->diffuseConstant;
-            }
+    }
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_ATTR_KERNELUNITLENGTH:
@@ -166,7 +195,15 @@ sp_feDiffuseLighting_set(SPObject *object, unsigned int key, gchar const *value)
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_PROP_LIGHTING_COLOR:
-            feDiffuseLighting->lighting_color = sp_svg_read_color(value, 0xffffffff);
+            cend_ptr = NULL;
+            feDiffuseLighting->lighting_color = sp_svg_read_color(value, &cend_ptr, 0xffffffff);
+            //if a value was read
+            if (cend_ptr) {
+                feDiffuseLighting->lighting_color_set = TRUE; 
+            } else {
+                //lighting_color already contains the default value
+                feDiffuseLighting->lighting_color_set = FALSE; 
+            }
             if (feDiffuseLighting->renderer) {
                 feDiffuseLighting->renderer->lighting_color = feDiffuseLighting->lighting_color;
             }
@@ -215,13 +252,23 @@ sp_feDiffuseLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint fl
             repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
         }
     }
-
-    sp_repr_set_css_double(repr, "surfaceScale", fediffuselighting->surfaceScale);
-    sp_repr_set_css_double(repr, "diffuseConstant", fediffuselighting->diffuseConstant);
+    
+    if (fediffuselighting->surfaceScale_set)
+        sp_repr_set_css_double(repr, "surfaceScale", fediffuselighting->surfaceScale);
+    else
+        repr->setAttribute("surfaceScale", NULL);
+    if (fediffuselighting->diffuseConstant_set)
+        sp_repr_set_css_double(repr, "diffuseConstant", fediffuselighting->diffuseConstant);
+    else
+        repr->setAttribute("diffuseConstant", NULL);
    /*TODO kernelUnits */ 
-    gchar c[64];
-    sp_svg_write_color(c, 64, fediffuselighting->lighting_color);
-    repr->setAttribute("lighting-color", c);
+    if (fediffuselighting->lighting_color_set) {
+        gchar c[64];
+        sp_svg_write_color(c, 64, fediffuselighting->lighting_color);
+        repr->setAttribute("lighting-color", c);
+    } else
+        repr->setAttribute("lighting-color", NULL);
+        
     if (((SPObjectClass *) feDiffuseLighting_parent_class)->write) {
         ((SPObjectClass *) feDiffuseLighting_parent_class)->write(object, repr, flags);
     }
index 15988b306663251bcf9d9fe2d87efe694de7dd32..7d5bca8a371e836483265d5e5d2b218400c6aa60 100644 (file)
@@ -27,11 +27,18 @@ class SPFeDiffuseLightingClass;
 
 struct SPFeDiffuseLighting : public SPFilterPrimitive {
     /** DIFFUSELIGHTING ATTRIBUTES HERE */
+    /** surfaceScale attribute */
     gfloat surfaceScale;
+    guint surfaceScale_set : 1;
+    /** diffuseConstant attribute */
     gfloat diffuseConstant;
+    guint diffuseConstant_set : 1;
+    /** kernelUnitLength attribute */
     NumberOptNumber kernelUnitLength;
+    /** lighting-color property */
     guint32 lighting_color;
-
+    guint lighting_color_set : 1;
+    /** pointer to the associated renderer */
     NR::FilterDiffuseLighting *renderer;
 };
 
index 2b9ef8ff57f39a7593e8e7f5a105da9bf1c5974b..a878e1ad7cf23dc63c9caac050e30a7e392cc47f 100644 (file)
@@ -84,6 +84,8 @@ sp_fedistantlight_init(SPFeDistantLight *fedistantlight)
 {
     fedistantlight->azimuth = 0;
     fedistantlight->elevation = 0;
+    fedistantlight->azimuth_set = FALSE;
+    fedistantlight->elevation_set = FALSE;
 }
 
 /**
@@ -129,10 +131,20 @@ static void
 sp_fedistantlight_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPFeDistantLight *fedistantlight = SP_FEDISTANTLIGHT(object);
-
+    gchar *end_ptr;
     switch (key) {
     case SP_ATTR_AZIMUTH:
-        fedistantlight->azimuth = g_ascii_strtod(value, NULL);
+        end_ptr =NULL;
+        if (value) {
+            fedistantlight->azimuth = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr) {
+                fedistantlight->azimuth_set = TRUE;
+            }
+        }
+        if (!value || !end_ptr) {
+                fedistantlight->azimuth_set = FALSE;
+                fedistantlight->azimuth = 0;
+        }
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -140,7 +152,17 @@ sp_fedistantlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_ELEVATION:
-        fedistantlight->elevation = g_ascii_strtod(value, NULL);
+        end_ptr =NULL;
+        if (value) {
+            fedistantlight->elevation = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr) {
+                fedistantlight->elevation_set = TRUE;
+            }
+        }
+        if (!value || !end_ptr) {
+                fedistantlight->elevation_set = FALSE;
+                fedistantlight->elevation = 0;
+        }
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -186,9 +208,11 @@ sp_fedistantlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags
     if (!repr) {
         repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
     }
-
-    sp_repr_set_css_double(repr, "azimuth", fedistantlight->azimuth);
-    sp_repr_set_css_double(repr, "elevation", fedistantlight->elevation);
+    
+    if (fedistantlight->azimuth_set)
+        sp_repr_set_css_double(repr, "azimuth", fedistantlight->azimuth);
+    if (fedistantlight->elevation_set)
+        sp_repr_set_css_double(repr, "elevation", fedistantlight->elevation);
     
     if (((SPObjectClass *) feDistantLight_parent_class)->write) {
         ((SPObjectClass *) feDistantLight_parent_class)->write(object, repr, flags);
index 32a63f6581da94b64428bd06af7b279a0a3d483d..21edbc56c586365faff1a342dd47fefec891f669 100644 (file)
@@ -33,10 +33,10 @@ struct SPFeDistantLight : public SPObject {
 
     /** azimuth attribute */
     gfloat azimuth;
+    guint azimuth_set : 1;
     /** elevation attribute */
     gfloat elevation;
-
-    //other fields
+    guint elevation_set : 1;
 };
 
 struct SPFeDistantLightClass {
index 9d912da14a5400bf25e948e934b81000bd662ce6..88af356219cebd7fb9ba331488754e3a0e7f5286 100644 (file)
@@ -85,6 +85,10 @@ sp_fepointlight_init(SPFePointLight *fepointlight)
     fepointlight->x = 0;
     fepointlight->y = 0;
     fepointlight->z = 0;
+    
+    fepointlight->x_set = FALSE;
+    fepointlight->y_set = FALSE;
+    fepointlight->z_set = FALSE;
 }
 
 /**
@@ -131,10 +135,20 @@ static void
 sp_fepointlight_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPFePointLight *fepointlight = SP_FEPOINTLIGHT(object);
-
+    gchar *end_ptr;
     switch (key) {
     case SP_ATTR_X:
-        fepointlight->x = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fepointlight->x = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr) {
+                fepointlight->x_set = TRUE;
+            }
+        }
+        if (!value || !end_ptr) {
+            fepointlight->x = 0;
+            fepointlight->x_set = FALSE;
+        }
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -142,7 +156,17 @@ sp_fepointlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_Y:
-        fepointlight->y = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fepointlight->y = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr) {
+                fepointlight->y_set = TRUE;
+            }
+        }
+        if (!value || !end_ptr) {
+            fepointlight->y = 0;
+            fepointlight->y_set = FALSE;
+        }
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -150,7 +174,17 @@ sp_fepointlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_Z:
-        fepointlight->z = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fepointlight->z = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr) {
+                fepointlight->z_set = TRUE;
+            }
+        }
+        if (!value || !end_ptr) {
+            fepointlight->z = 0;
+            fepointlight->z_set = FALSE;
+        }
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -197,10 +231,13 @@ sp_fepointlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
     if (!repr) {
         repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
     }
-
-    sp_repr_set_css_double(repr, "x", fepointlight->x);
-    sp_repr_set_css_double(repr, "y", fepointlight->y);
-    sp_repr_set_css_double(repr, "z", fepointlight->z);
+    
+    if (fepointlight->x_set)
+        sp_repr_set_css_double(repr, "x", fepointlight->x);
+    if (fepointlight->y_set)
+        sp_repr_set_css_double(repr, "y", fepointlight->y);
+    if (fepointlight->z_set)
+        sp_repr_set_css_double(repr, "z", fepointlight->z);
     
     if (((SPObjectClass *) fePointLight_parent_class)->write) {
         ((SPObjectClass *) fePointLight_parent_class)->write(object, repr, flags);
index 88d399868b12a7c97795f1aca8dc2154cdeec421..915d726afb5dc0479c527b4093663fd2949ace5f 100644 (file)
@@ -33,10 +33,13 @@ struct SPFePointLight : public SPObject {
 
     /** x coordinate of the light source */
     gfloat x; 
+    guint x_set : 1;
     /** y coordinate of the light source */
     gfloat y; 
+    guint y_set : 1;
     /** z coordinate of the light source */
     gfloat z; 
+    guint z_set : 1;
 
     //other fields
 };
index 85f2aa862a6fba9cc4238a13501641d1f8faa046..27f8cf8ba78471267aca0f8dfa8c7b0f46dd1795 100644 (file)
@@ -100,6 +100,11 @@ sp_feSpecularLighting_init(SPFeSpecularLighting *feSpecularLighting)
     feSpecularLighting->lighting_color = 0xffffffff;
     //TODO kernelUnit
     feSpecularLighting->renderer = NULL;
+    
+    feSpecularLighting->surfaceScale_set = FALSE;
+    feSpecularLighting->specularConstant_set = FALSE;
+    feSpecularLighting->specularExponent_set = FALSE;
+    feSpecularLighting->lighting_color_set = FALSE;
 }
 
 /**
@@ -140,26 +145,67 @@ static void
 sp_feSpecularLighting_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPFeSpecularLighting *feSpecularLighting = SP_FESPECULARLIGHTING(object);
-    
+    gchar const *cend_ptr = NULL;
+    gchar *end_ptr = NULL;
     switch(key) {
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
 //TODO test forbidden values
         case SP_ATTR_SURFACESCALE:
-            feSpecularLighting->surfaceScale = g_ascii_strtod(value, NULL);
+            end_ptr = NULL;
+            if (value) {
+                feSpecularLighting->surfaceScale = g_ascii_strtod(value, &end_ptr);
+                if (end_ptr) {
+                    feSpecularLighting->surfaceScale_set = TRUE;
+                } else {
+                    g_warning("feSpecularLighting: surfaceScale should be a number ... defaulting to 1");
+                }
+
+            }
+            //if the attribute is not set or has an unreadable value
+            if (!value || !end_ptr) {
+                feSpecularLighting->surfaceScale = 1;
+                feSpecularLighting->surfaceScale_set = FALSE;
+            }
             if (feSpecularLighting->renderer) {
                 feSpecularLighting->renderer->surfaceScale = feSpecularLighting->surfaceScale;
             }
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_ATTR_SPECULARCONSTANT:
-            feSpecularLighting->specularConstant = g_ascii_strtod(value, NULL);
+            end_ptr = NULL;
+            if (value) {
+                feSpecularLighting->specularConstant = g_ascii_strtod(value, &end_ptr);
+                if (end_ptr && feSpecularLighting->specularConstant >= 0) {
+                    feSpecularLighting->specularConstant_set = TRUE;
+                } else {
+                    end_ptr = NULL;
+                    g_warning("feSpecularLighting: specularConstant should be a positive number ... defaulting to 1");
+                }
+            }
+            if (!value || !end_ptr) {
+                feSpecularLighting->specularConstant = 1;
+                feSpecularLighting->specularConstant_set = FALSE;
+            }
             if (feSpecularLighting->renderer) {
                 feSpecularLighting->renderer->specularConstant = feSpecularLighting->specularConstant;
             }
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_ATTR_SPECULAREXPONENT:
-            feSpecularLighting->specularExponent = g_ascii_strtod(value, NULL);
+            end_ptr = NULL;
+            if (value) {
+                feSpecularLighting->specularExponent = g_ascii_strtod(value, &end_ptr);
+                if (feSpecularLighting->specularExponent >= 1 && feSpecularLighting->specularExponent <= 128) {
+                    feSpecularLighting->specularExponent_set = TRUE;
+                } else {
+                    end_ptr = NULL;
+                    g_warning("feSpecularLighting: specularExponent should be a number in range [1, 128] ... defaulting to 1");
+                }
+            } 
+            if (!value || !end_ptr) {
+                feSpecularLighting->specularExponent = 1;
+                feSpecularLighting->specularExponent_set = FALSE;
+            }
             if (feSpecularLighting->renderer) {
                 feSpecularLighting->renderer->specularExponent = feSpecularLighting->specularExponent;
             }
@@ -175,7 +221,15 @@ sp_feSpecularLighting_set(SPObject *object, unsigned int key, gchar const *value
             object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
         case SP_PROP_LIGHTING_COLOR:
-            feSpecularLighting->lighting_color = sp_svg_read_color(value, 0xffffffff);
+            cend_ptr = NULL;
+            feSpecularLighting->lighting_color = sp_svg_read_color(value, &cend_ptr, 0xffffffff);
+            //if a value was read
+            if (cend_ptr) {
+                feSpecularLighting->lighting_color_set = TRUE;
+            } else {
+                //lighting_color already contains the default value
+                feSpecularLighting->lighting_color_set = FALSE;
+            }
             if (feSpecularLighting->renderer) {
                 feSpecularLighting->renderer->lighting_color = feSpecularLighting->lighting_color;
             }
@@ -225,14 +279,18 @@ sp_feSpecularLighting_write(SPObject *object, Inkscape::XML::Node *repr, guint f
             repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
         }
     }
-
-    sp_repr_set_css_double(repr, "surfaceScale", fespecularlighting->surfaceScale);
-    sp_repr_set_css_double(repr, "specularConstant", fespecularlighting->specularConstant);
-    sp_repr_set_css_double(repr, "specularExponent", fespecularlighting->specularExponent);
+    if (fespecularlighting->surfaceScale_set)
+        sp_repr_set_css_double(repr, "surfaceScale", fespecularlighting->surfaceScale);
+    if (fespecularlighting->specularConstant_set)
+        sp_repr_set_css_double(repr, "specularConstant", fespecularlighting->specularConstant);
+    if (fespecularlighting->specularExponent_set)
+        sp_repr_set_css_double(repr, "specularExponent", fespecularlighting->specularExponent);
    /*TODO kernelUnits */ 
-    gchar c[64];
-    sp_svg_write_color(c, 64, fespecularlighting->lighting_color);
-    repr->setAttribute("lighting-color", c);
+    if (fespecularlighting->lighting_color_set) {
+        gchar c[64];
+        sp_svg_write_color(c, 64, fespecularlighting->lighting_color);
+        repr->setAttribute("lighting-color", c);
+    }
     if (((SPObjectClass *) feSpecularLighting_parent_class)->write) {
         ((SPObjectClass *) feSpecularLighting_parent_class)->write(object, repr, flags);
     }
index 9aa38b53e807fcc07e11233b755fb43becfca9bc..5d2194c2fb3481ab18d7b4521e74c7f90c940cad 100644 (file)
@@ -27,11 +27,20 @@ class SPFeSpecularLightingClass;
 
 struct SPFeSpecularLighting : public SPFilterPrimitive {
     /** SPECULARLIGHTING ATTRIBUTES HERE */
+    /** surfaceScale attribute */
     gfloat surfaceScale;
+    guint surfaceScale_set : 1;
+    /** specularConstant attribute */
     gfloat specularConstant;
+    guint specularConstant_set : 1;
+    /** specularConstant attribute */
     gfloat specularExponent;
+    guint specularExponent_set : 1;
+    /** kernelUnitLenght attribute */
     NumberOptNumber kernelUnitLength;
+    /** lighting-color property */
     guint32 lighting_color;
+    guint lighting_color_set : 1;
 
     NR::FilterSpecularLighting *renderer;
 };
index d5ae5306cd3a6b927f6779952e7f4adde607166b..2730b0d8fcdbc073ec1e14429c131e81304d0523 100644 (file)
@@ -90,6 +90,15 @@ sp_fespotlight_init(SPFeSpotLight *fespotlight)
     fespotlight->pointsAtZ = 0;
     fespotlight->specularExponent = 1;
     fespotlight->limitingConeAngle = 90;
+    
+    fespotlight->x_set = FALSE;
+    fespotlight->y_set = FALSE;
+    fespotlight->z_set = FALSE;
+    fespotlight->pointsAtX_set = FALSE;
+    fespotlight->pointsAtY_set = FALSE;
+    fespotlight->pointsAtZ_set = FALSE;
+    fespotlight->specularExponent_set = FALSE;
+    fespotlight->limitingConeAngle_set = FALSE;
 }
 
 /**
@@ -141,10 +150,20 @@ static void
 sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
 {
     SPFeSpotLight *fespotlight = SP_FESPOTLIGHT(object);
-
+    gchar *end_ptr;
+    
     switch (key) {
     case SP_ATTR_X:
-        fespotlight->x = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->x = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->x_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->x = 0;
+            fespotlight->x_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -152,7 +171,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_Y:
-        fespotlight->y = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->y = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->y_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->y = 0;
+            fespotlight->y_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -160,7 +188,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_Z:
-        fespotlight->z = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->z = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->z_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->z = 0;
+            fespotlight->z_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -168,7 +205,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_POINTSATX:
-        fespotlight->pointsAtX = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->pointsAtX = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->pointsAtX_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->pointsAtX = 0;
+            fespotlight->pointsAtX_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -176,7 +222,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_POINTSATY:
-        fespotlight->pointsAtY = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->pointsAtY = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->pointsAtY_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->pointsAtY = 0;
+            fespotlight->pointsAtY_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -184,7 +239,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_POINTSATZ:
-        fespotlight->pointsAtZ = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->pointsAtZ = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->pointsAtZ_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->pointsAtZ = 0;
+            fespotlight->pointsAtZ_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -192,7 +256,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_SPECULAREXPONENT:
-        fespotlight->specularExponent = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->specularExponent = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->specularExponent_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->specularExponent = 1;
+            fespotlight->specularExponent_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -200,7 +273,16 @@ sp_fespotlight_set(SPObject *object, unsigned int key, gchar const *value)
         }
         break;
     case SP_ATTR_LIMITINGCONEANGLE:
-        fespotlight->limitingConeAngle = g_ascii_strtod(value, NULL);
+        end_ptr = NULL;
+        if (value) {
+            fespotlight->limitingConeAngle = g_ascii_strtod(value, &end_ptr);
+            if (end_ptr)
+                fespotlight->limitingConeAngle_set = TRUE;
+        }
+        if(!value || !end_ptr) {
+            fespotlight->limitingConeAngle = 90;
+            fespotlight->limitingConeAngle_set = FALSE;
+        } 
         if (object->parent &&
                 (SP_IS_FEDIFFUSELIGHTING(object->parent) ||
                  SP_IS_FESPECULARLIGHTING(object->parent))) {
@@ -252,15 +334,23 @@ sp_fespotlight_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
     if (!repr) {
         repr = SP_OBJECT_REPR(object)->duplicate(NULL); // FIXME
     }
-
-    sp_repr_set_css_double(repr, "x", fespotlight->x);
-    sp_repr_set_css_double(repr, "y", fespotlight->y);
-    sp_repr_set_css_double(repr, "z", fespotlight->z);
-    sp_repr_set_css_double(repr, "pointsAtX", fespotlight->pointsAtX);
-    sp_repr_set_css_double(repr, "pointsAtY", fespotlight->pointsAtY);
-    sp_repr_set_css_double(repr, "pointsAtZ", fespotlight->pointsAtZ);
-    sp_repr_set_css_double(repr, "specularExponent", fespotlight->specularExponent);
-    sp_repr_set_css_double(repr, "limitingConeAngle", fespotlight->limitingConeAngle);
+    
+    if (fespotlight->x_set)
+        sp_repr_set_css_double(repr, "x", fespotlight->x);
+    if (fespotlight->y_set)
+        sp_repr_set_css_double(repr, "y", fespotlight->y);
+    if (fespotlight->z_set)
+        sp_repr_set_css_double(repr, "z", fespotlight->z);
+    if (fespotlight->pointsAtX_set)
+        sp_repr_set_css_double(repr, "pointsAtX", fespotlight->pointsAtX);
+    if (fespotlight->pointsAtY_set)
+        sp_repr_set_css_double(repr, "pointsAtY", fespotlight->pointsAtY);
+    if (fespotlight->pointsAtZ_set)
+        sp_repr_set_css_double(repr, "pointsAtZ", fespotlight->pointsAtZ);
+    if (fespotlight->specularExponent_set)
+        sp_repr_set_css_double(repr, "specularExponent", fespotlight->specularExponent);
+    if (fespotlight->limitingConeAngle_set)
+        sp_repr_set_css_double(repr, "limitingConeAngle", fespotlight->limitingConeAngle);
     
     if (((SPObjectClass *) feSpotLight_parent_class)->write) {
         ((SPObjectClass *) feSpotLight_parent_class)->write(object, repr, flags);
index d0b04250f20b3532fa131f96b0a836c7e99d9b62..d48cf6daa73ba5f22385135e7a12f9d6cc0c7408 100644 (file)
@@ -33,20 +33,28 @@ struct SPFeSpotLight : public SPObject {
 
     /** x coordinate of the light source */
     gfloat x; 
+    guint x_set : 1;
     /** y coordinate of the light source */
     gfloat y; 
+    guint y_set : 1;
     /** z coordinate of the light source */
     gfloat z; 
+    guint z_set : 1;
     /** x coordinate of the point the source is pointing at */
     gfloat pointsAtX;
+    guint pointsAtX_set : 1;
     /** y coordinate of the point the source is pointing at */
     gfloat pointsAtY;
+    guint pointsAtY_set : 1;
     /** z coordinate of the point the source is pointing at */
     gfloat pointsAtZ;
+    guint pointsAtZ_set : 1;
     /** specular exponent (focus of the light) */
     gfloat specularExponent;
+    guint specularExponent_set : 1;
     /** limiting cone angle */
     gfloat limitingConeAngle;
+    guint limitingConeAngle_set : 1;
     //other fields
 };