Code

Added test script I thought was already added.
[inkscape.git] / src / filters / convolvematrix.cpp
index a930bc4e75dc5cae0199543d26d3248d7b0b6039..3e1c36f0ad994afd8f6d3cc3edfc88a174a658c4 100644 (file)
@@ -39,7 +39,7 @@ static void sp_feConvolveMatrix_release(SPObject *object);
 static void sp_feConvolveMatrix_set(SPObject *object, unsigned int key, gchar const *value);
 static void sp_feConvolveMatrix_update(SPObject *object, SPCtx *ctx, guint flags);
 static Inkscape::XML::Node *sp_feConvolveMatrix_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
-static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter);
+static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, Inkscape::Filters::Filter *filter);
 
 static SPFilterPrimitiveClass *feConvolveMatrix_parent_class;
 
@@ -88,7 +88,7 @@ sp_feConvolveMatrix_init(SPFeConvolveMatrix *feConvolveMatrix)
     feConvolveMatrix->order.set("3 3");
     feConvolveMatrix->targetX = 1;
     feConvolveMatrix->targetY = 1;
-    feConvolveMatrix->edgeMode = NR::CONVOLVEMATRIX_EDGEMODE_DUPLICATE;
+    feConvolveMatrix->edgeMode = Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_DUPLICATE;
     feConvolveMatrix->preserveAlpha = false;
 
     //some helper variables:
@@ -131,20 +131,20 @@ sp_feConvolveMatrix_release(SPObject *object)
         ((SPObjectClass *) feConvolveMatrix_parent_class)->release(object);
 }
 
-static NR::FilterConvolveMatrixEdgeMode sp_feConvolveMatrix_read_edgeMode(gchar const *value){
-    if (!value) return NR::CONVOLVEMATRIX_EDGEMODE_DUPLICATE; //duplicate is default
+static Inkscape::Filters::FilterConvolveMatrixEdgeMode sp_feConvolveMatrix_read_edgeMode(gchar const *value){
+    if (!value) return Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_DUPLICATE; //duplicate is default
     switch(value[0]){
         case 'd':
-            if (strncmp(value, "duplicate", 9) == 0) return NR::CONVOLVEMATRIX_EDGEMODE_DUPLICATE;
+            if (strncmp(value, "duplicate", 9) == 0) return Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_DUPLICATE;
             break;
         case 'w':
-            if (strncmp(value, "wrap", 4) == 0) return NR::CONVOLVEMATRIX_EDGEMODE_WRAP;
+            if (strncmp(value, "wrap", 4) == 0) return Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_WRAP;
             break;
         case 'n':
-            if (strncmp(value, "none", 4) == 0) return NR::CONVOLVEMATRIX_EDGEMODE_NONE;
+            if (strncmp(value, "none", 4) == 0) return Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_NONE;
             break;
     }
-    return NR::CONVOLVEMATRIX_EDGEMODE_DUPLICATE; //duplicate is default
+    return Inkscape::Filters::CONVOLVEMATRIX_EDGEMODE_DUPLICATE; //duplicate is default
 }
 
 /**
@@ -158,7 +158,7 @@ sp_feConvolveMatrix_set(SPObject *object, unsigned int key, gchar const *value)
     double read_num;
     int read_int;
     bool read_bool;
-    NR::FilterConvolveMatrixEdgeMode read_mode;
+    Inkscape::Filters::FilterConvolveMatrixEdgeMode read_mode;
    
     switch(key) {
        /*DEAL WITH SETTING ATTRIBUTES HERE*/
@@ -175,31 +175,38 @@ sp_feConvolveMatrix_set(SPObject *object, unsigned int key, gchar const *value)
             if (value){
                 feConvolveMatrix->kernelMatrixIsSet = true;
                 feConvolveMatrix->kernelMatrix = helperfns_read_vector(value, (int) (feConvolveMatrix->order.getNumber() * feConvolveMatrix->order.getOptNumber()));
+                if (! feConvolveMatrix->divisorIsSet) {
+                    feConvolveMatrix->divisor = 0;
+                    for (unsigned int i = 0; i< feConvolveMatrix->kernelMatrix.size(); i++)
+                        feConvolveMatrix->divisor += feConvolveMatrix->kernelMatrix[i];
+                    if (feConvolveMatrix->divisor == 0) feConvolveMatrix->divisor = 1;
+                }
                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
             } else {
                 g_warning("For feConvolveMatrix you MUST pass a kernelMatrix parameter!");
             }
             break;
         case SP_ATTR_DIVISOR:
-            if (!value){
-                read_num = 1; 
-            } else {
+            if (value) { 
                 read_num = helperfns_read_number(value);
                 if (read_num == 0) {
-                    if (feConvolveMatrix->kernelMatrixIsSet){
-                        g_warning("You shouldn't pass a divisor value equal to 0! Assuming the sum of all values in kernelMatrix as the default value.");
+                    // This should actually be an error, but given our UI it is more useful to simply set divisor to the default.
+                    if (feConvolveMatrix->kernelMatrixIsSet) {
                         for (unsigned int i = 0; i< feConvolveMatrix->kernelMatrix.size(); i++)
                             read_num += feConvolveMatrix->kernelMatrix[i];
-                    } else {
-                        g_warning("You shouldn't pass a divisor value equal to 0! Assuming 1 as the default value.");
-                        read_num = 1;
                     }
+                    if (read_num == 0) read_num = 1;
+                    if (feConvolveMatrix->divisorIsSet || feConvolveMatrix->divisor!=read_num) {
+                        feConvolveMatrix->divisorIsSet = false;
+                        feConvolveMatrix->divisor = read_num;
+                        object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                    }
+                } else if (!feConvolveMatrix->divisorIsSet || feConvolveMatrix->divisor!=read_num) {
+                    feConvolveMatrix->divisorIsSet = true;
+                    feConvolveMatrix->divisor = read_num;
+                    object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
                 }
             }
-            if (read_num != feConvolveMatrix->divisor){
-                feConvolveMatrix->divisor = read_num;
-                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
-            }
             break;
         case SP_ATTR_BIAS:
             read_num = 0;
@@ -210,27 +217,31 @@ sp_feConvolveMatrix_set(SPObject *object, unsigned int key, gchar const *value)
             }
             break;
         case SP_ATTR_TARGETX:
-            read_int = (int) helperfns_read_number(value);
-            if (read_int < 0 || read_int > feConvolveMatrix->order.getNumber()){
-                g_warning("targetX must be a value between 0 and orderX! Assuming orderX as default value.");
-                read_int = (int) feConvolveMatrix->order.getNumber();
-            }
-            feConvolveMatrix->targetXIsSet = true;
-            if (read_int != feConvolveMatrix->targetX){
-                feConvolveMatrix->targetX = read_int;
-                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+            if (value) {
+                read_int = (int) helperfns_read_number(value);
+                if (read_int < 0 || read_int > feConvolveMatrix->order.getNumber()){
+                    g_warning("targetX must be a value between 0 and orderX! Assuming floor(orderX/2) as default value.");
+                    read_int = (int) floor(feConvolveMatrix->order.getNumber()/2.0);
+                }
+                feConvolveMatrix->targetXIsSet = true;
+                if (read_int != feConvolveMatrix->targetX){
+                    feConvolveMatrix->targetX = read_int;
+                    object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                }
             }
             break;
         case SP_ATTR_TARGETY:
-            read_int = (int) helperfns_read_number(value);
-            if (read_int < 0 || read_int > feConvolveMatrix->order.getOptNumber()){
-                g_warning("targetY must be a value between 0 and orderY! Assuming orderY as default value.");
-                read_int = (int) feConvolveMatrix->order.getOptNumber();
-            }
-            feConvolveMatrix->targetYIsSet = true;
-            if (read_int != feConvolveMatrix->targetY){
-                feConvolveMatrix->targetY = read_int;
-                object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+            if (value) {
+                read_int = (int) helperfns_read_number(value);
+                if (read_int < 0 || read_int > feConvolveMatrix->order.getOptNumber()){
+                    g_warning("targetY must be a value between 0 and orderY! Assuming floor(orderY/2) as default value.");
+                    read_int = (int) floor(feConvolveMatrix->order.getOptNumber()/2.0);
+                }
+                feConvolveMatrix->targetYIsSet = true;
+                if (read_int != feConvolveMatrix->targetY){
+                    feConvolveMatrix->targetY = read_int;
+                    object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+                }
             }
             break;
         case SP_ATTR_EDGEMODE:
@@ -286,16 +297,13 @@ sp_feConvolveMatrix_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feConvolveMatrix_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
 {
-    // Inkscape-only object, not copied during an "plain SVG" dump:
-    if (flags & SP_OBJECT_WRITE_EXT) {
-        if (repr) {
-            // is this sane?
-            //repr->mergeFrom(SP_OBJECT_REPR(object), "id");
-        } else {
-            repr = SP_OBJECT_REPR(object)->duplicate(doc);
-        }
+    /* TODO: Don't just clone, but create a new repr node and write all
+     * relevant values into it */
+    if (!repr) {
+        repr = SP_OBJECT_REPR(object)->duplicate(doc);
     }
 
+
     if (((SPObjectClass *) feConvolveMatrix_parent_class)->write) {
         ((SPObjectClass *) feConvolveMatrix_parent_class)->write(object, doc, repr, flags);
     }
@@ -303,15 +311,15 @@ sp_feConvolveMatrix_write(SPObject *object, Inkscape::XML::Document *doc, Inksca
     return repr;
 }
 
-static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+static void sp_feConvolveMatrix_build_renderer(SPFilterPrimitive *primitive, Inkscape::Filters::Filter *filter) {
     g_assert(primitive != NULL);
     g_assert(filter != NULL);
 
     SPFeConvolveMatrix *sp_convolve = SP_FECONVOLVEMATRIX(primitive);
 
-    int primitive_n = filter->add_primitive(NR::NR_FILTER_CONVOLVEMATRIX);
-    NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
-    NR::FilterConvolveMatrix *nr_convolve = dynamic_cast<NR::FilterConvolveMatrix*>(nr_primitive);
+    int primitive_n = filter->add_primitive(Inkscape::Filters::NR_FILTER_CONVOLVEMATRIX);
+    Inkscape::Filters::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
+    Inkscape::Filters::FilterConvolveMatrix *nr_convolve = dynamic_cast<Inkscape::Filters::FilterConvolveMatrix*>(nr_primitive);
     g_assert(nr_convolve != NULL);
 
     sp_filter_primitive_renderer_common(primitive, nr_primitive);