Code

Fixed several cases of bad SVG being written from filters
authorkiirala <kiirala@users.sourceforge.net>
Sun, 17 May 2009 21:43:43 +0000 (21:43 +0000)
committerkiirala <kiirala@users.sourceforge.net>
Sun, 17 May 2009 21:43:43 +0000 (21:43 +0000)
20 files changed:
src/filters/blend.cpp
src/filters/colormatrix.cpp
src/filters/componenttransfer.cpp
src/filters/composite.cpp
src/filters/convolvematrix.cpp
src/filters/diffuselighting.cpp
src/filters/displacementmap.cpp
src/filters/flood.cpp
src/filters/image.cpp
src/filters/merge.cpp
src/filters/morphology.cpp
src/filters/offset.cpp
src/filters/specularlighting.cpp
src/filters/tile.cpp
src/filters/turbulence.cpp
src/sp-filter-primitive.cpp
src/sp-filter-primitive.h
src/sp-filter.cpp
src/sp-filter.h
src/sp-gaussian-blur.cpp

index 709130adaa4f2665f7fdc23ccab6023741a588f9..5998d7be335021cb0ea6b4aeefa97e69c8a9efb9 100644 (file)
@@ -96,6 +96,8 @@ sp_feBlend_init(SPFeBlend *feBlend)
 static void
 sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
 {
+    SPFeBlend *blend = SP_FEBLEND(object);
+
     if (((SPObjectClass *) feBlend_parent_class)->build) {
         ((SPObjectClass *) feBlend_parent_class)->build(object, document, repr);
     }
@@ -103,6 +105,16 @@ sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *re
     /*LOAD ATTRIBUTES FROM REPR HERE*/
     sp_object_read_attr(object, "mode");
     sp_object_read_attr(object, "in2");
+
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    if (blend->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        blend->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        blend->in2 = sp_filter_primitive_name_previous_out(blend);
+        repr->setAttribute("in2", sp_filter_name_for_image(parent, blend->in2));
+    }
 }
 
 /**
@@ -187,11 +199,23 @@ sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value)
 static void
 sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags)
 {
+    SPFeBlend *blend = SP_FEBLEND(object);
+
     if (flags & SP_OBJECT_MODIFIED_FLAG) {
         sp_object_read_attr(object, "mode");
         sp_object_read_attr(object, "in2");
     }
 
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    if (blend->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        blend->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        blend->in2 = sp_filter_primitive_name_previous_out(blend);
+        object->repr->setAttribute("in2", sp_filter_name_for_image(parent, blend->in2));
+    }
+
     if (((SPObjectClass *) feBlend_parent_class)->update) {
         ((SPObjectClass *) feBlend_parent_class)->update(object, ctx, flags);
     }
@@ -203,16 +227,44 @@ sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feBlend_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);
+    SPFeBlend *blend = SP_FEBLEND(object);
+    SPFilter *parent = SP_FILTER(object->parent);
+
+    if (!repr) {
+        repr = doc->createElement("svg:feBlend");
+    }
+
+    gchar const *out_name = sp_filter_name_for_image(parent, blend->in2);
+    if (out_name) {
+        repr->setAttribute("in2", out_name);
+    } else {
+        SPObject *i = parent->children;
+        while (i && i->next != object) i = i->next;
+        SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
+        out_name = sp_filter_name_for_image(parent, i_prim->image_out);
+        repr->setAttribute("in2", out_name);
+        if (!out_name) {
+            g_warning("Unable to set in2 for feBlend");
         }
     }
 
+    char const *mode;
+    switch(blend->blend_mode) {
+        case Inkscape::Filters::BLEND_NORMAL:
+            mode = "normal"; break;
+        case Inkscape::Filters::BLEND_MULTIPLY:
+            mode = "multiply"; break;
+        case Inkscape::Filters::BLEND_SCREEN:
+            mode = "screen"; break;
+        case Inkscape::Filters::BLEND_DARKEN:
+            mode = "darken"; break;
+        case Inkscape::Filters::BLEND_LIGHTEN:
+            mode = "lighten"; break;
+        default:
+            mode = 0;
+    }
+    repr->setAttribute("mode", mode);
+
     if (((SPObjectClass *) feBlend_parent_class)->write) {
         ((SPObjectClass *) feBlend_parent_class)->write(object, doc, repr, flags);
     }
index a6096bdb641009bfa4a7c526f24b72b7e3a1a5ec..55cfcbeb78ed20c6b0833d2210e592a536bc9f01 100644 (file)
@@ -188,14 +188,10 @@ sp_feColorMatrix_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feColorMatrix_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 *) feColorMatrix_parent_class)->write) {
index f2f68e05dc297731b023231ae63877805b3350b2..557d884e0ffb797f3d2fe5f1d90d5bc1e9488b9e 100644 (file)
@@ -220,14 +220,10 @@ sp_feComponentTransfer_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feComponentTransfer_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 *) feComponentTransfer_parent_class)->write) {
index 75ee0fd27301e0a752e49630e86d912827252e7a..93c692f94d14f24749b9c116e954b1340ab4106c 100644 (file)
@@ -99,16 +99,26 @@ sp_feComposite_build(SPObject *object, SPDocument *document, Inkscape::XML::Node
         ((SPObjectClass *) feComposite_parent_class)->build(object, document, repr);
     }
 
-    SPFeComposite *composite = SP_FECOMPOSITE(object);
+    SPFeComposite *comp = SP_FECOMPOSITE(object);
 
     sp_object_read_attr(object, "operator");
-    if (composite->composite_operator == COMPOSITE_ARITHMETIC) {
+    if (comp->composite_operator == COMPOSITE_ARITHMETIC) {
         sp_object_read_attr(object, "k1");
         sp_object_read_attr(object, "k2");
         sp_object_read_attr(object, "k3");
         sp_object_read_attr(object, "k4");
     }
     sp_object_read_attr(object, "in2");
+
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    if (comp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        comp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        comp->in2 = sp_filter_primitive_name_previous_out(comp);
+        repr->setAttribute("in2", sp_filter_name_for_image(parent, comp->in2));
+    }
 }
 
 /**
@@ -214,6 +224,8 @@ sp_feComposite_set(SPObject *object, unsigned int key, gchar const *value)
 static void
 sp_feComposite_update(SPObject *object, SPCtx *ctx, guint flags)
 {
+    SPFeComposite *comp = SP_FECOMPOSITE(object);
+
     if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
                  SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
 
@@ -221,6 +233,16 @@ sp_feComposite_update(SPObject *object, SPCtx *ctx, guint flags)
 
     }
 
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    if (comp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        comp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        comp->in2 = sp_filter_primitive_name_previous_out(comp);
+        object->repr->setAttribute("in2", sp_filter_name_for_image(parent, comp->in2));
+    }
+
     if (((SPObjectClass *) feComposite_parent_class)->update) {
         ((SPObjectClass *) feComposite_parent_class)->update(object, ctx, flags);
     }
@@ -232,16 +254,58 @@ sp_feComposite_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feComposite_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);
+    SPFeComposite *comp = SP_FECOMPOSITE(object);
+    SPFilter *parent = SP_FILTER(object->parent);
+
+    if (!repr) {
+        repr = doc->createElement("svg:feComposite");
+    }
+
+    gchar const *out_name = sp_filter_name_for_image(parent, comp->in2);
+    if (out_name) {
+        repr->setAttribute("in2", out_name);
+    } else {
+        SPObject *i = parent->children;
+        while (i && i->next != object) i = i->next;
+        SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
+        out_name = sp_filter_name_for_image(parent, i_prim->image_out);
+        repr->setAttribute("in2", out_name);
+        if (!out_name) {
+            g_warning("Unable to set in2 for feComposite");
         }
     }
 
+    char const *comp_op;
+    switch (comp->composite_operator) {
+        case COMPOSITE_OVER:
+            comp_op = "over"; break;
+        case COMPOSITE_IN:
+            comp_op = "in"; break;
+        case COMPOSITE_OUT:
+            comp_op = "out"; break;
+        case COMPOSITE_ATOP:
+            comp_op = "atop"; break;
+        case COMPOSITE_XOR:
+            comp_op = "xor"; break;
+        case COMPOSITE_ARITHMETIC:
+            comp_op = "arithmetic"; break;
+        default:
+            comp_op = 0;
+    }
+    repr->setAttribute("operator", comp_op);
+
+    if (comp->composite_operator == COMPOSITE_ARITHMETIC) {
+        sp_repr_set_svg_double(repr, "k1", comp->k1);
+        sp_repr_set_svg_double(repr, "k2", comp->k2);
+        sp_repr_set_svg_double(repr, "k3", comp->k3);
+        sp_repr_set_svg_double(repr, "k4", comp->k4);
+    } else {
+        repr->setAttribute("k1", 0);
+        repr->setAttribute("k2", 0);
+        repr->setAttribute("k3", 0);
+        repr->setAttribute("k4", 0);
+    }
+
     if (((SPObjectClass *) feComposite_parent_class)->write) {
         ((SPObjectClass *) feComposite_parent_class)->write(object, doc, repr, flags);
     }
index 5cda2a1391f96a7317c69ac00dfe53db6b112404..3e1c36f0ad994afd8f6d3cc3edfc88a174a658c4 100644 (file)
@@ -297,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);
     }
index 9c68006edbe6febb904f9abcb84c52a2529d6649..bdc569083564712f170bc94d0b69e72105db86cc 100644 (file)
@@ -243,14 +243,11 @@ sp_feDiffuseLighting_write(SPObject *object, Inkscape::XML::Document *doc, Inksc
 {
     SPFeDiffuseLighting *fediffuselighting = SP_FEDIFFUSELIGHTING(object);
     
-    // 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 _and children_ into it */
+    if (!repr) {
+        repr = SP_OBJECT_REPR(object)->duplicate(doc);
+        //repr = doc->createElement("svg:feDiffuseLighting");
     }
     
     if (fediffuselighting->surfaceScale_set)
index 047ee46368928641668e2f5c74516f5da2169644..baa17d785f00452de09356050bfe7d599a259ade 100644 (file)
@@ -101,6 +101,17 @@ sp_feDisplacementMap_build(SPObject *object, SPDocument *document, Inkscape::XML
     sp_object_read_attr(object, "in2");
     sp_object_read_attr(object, "xChannelSelector");
     sp_object_read_attr(object, "yChannelSelector");
+
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    SPFeDisplacementMap *disp = SP_FEDISPLACEMENTMAP(object);
+    if (disp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        disp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        disp->in2 = sp_filter_primitive_name_previous_out(disp);
+        repr->setAttribute("in2", sp_filter_name_for_image(parent, disp->in2));
+    }
 }
 
 /**
@@ -199,27 +210,70 @@ sp_feDisplacementMap_update(SPObject *object, SPCtx *ctx, guint flags)
 
     }
 
+    /* Unlike normal in, in2 is required attribute. Make sure, we can call
+     * it by some name. */
+    SPFeDisplacementMap *disp = SP_FEDISPLACEMENTMAP(object);
+    if (disp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET ||
+        disp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT)
+    {
+        SPFilter *parent = SP_FILTER(object->parent);
+        disp->in2 = sp_filter_primitive_name_previous_out(disp);
+        object->repr->setAttribute("in2", sp_filter_name_for_image(parent, disp->in2));
+    }
+
     if (((SPObjectClass *) feDisplacementMap_parent_class)->update) {
         ((SPObjectClass *) feDisplacementMap_parent_class)->update(object, ctx, flags);
     }
 }
 
+static char const * get_channelselector_name(FilterDisplacementMapChannelSelector selector) {
+    switch(selector) {
+        case DISPLACEMENTMAP_CHANNEL_RED:
+            return "R";
+        case DISPLACEMENTMAP_CHANNEL_GREEN:
+            return "G";
+        case DISPLACEMENTMAP_CHANNEL_BLUE:
+            return "B";
+        case DISPLACEMENTMAP_CHANNEL_ALPHA:
+            return "A";
+        default:
+            return 0;
+    }
+}
+
 /**
  * Writes its settings to an incoming repr object, if any.
  */
 static Inkscape::XML::Node *
 sp_feDisplacementMap_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);
+    SPFeDisplacementMap *disp = SP_FEDISPLACEMENTMAP(object);
+    SPFilter *parent = SP_FILTER(object->parent);
+
+    if (!repr) {
+        repr = doc->createElement("svg:feDisplacementMap");
+    }
+
+    gchar const *out_name = sp_filter_name_for_image(parent, disp->in2);
+    if (out_name) {
+        repr->setAttribute("in2", out_name);
+    } else {
+        SPObject *i = parent->children;
+        while (i && i->next != object) i = i->next;
+        SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
+        out_name = sp_filter_name_for_image(parent, i_prim->image_out);
+        repr->setAttribute("in2", out_name);
+        if (!out_name) {
+            g_warning("Unable to set in2 for feDisplacementMap");
         }
     }
 
+    sp_repr_set_svg_double(repr, "scale", disp->scale);
+    repr->setAttribute("xChannelSelector",
+                       get_channelselector_name(disp->xChannelSelector));
+    repr->setAttribute("yChannelSelector",
+                       get_channelselector_name(disp->yChannelSelector));
+
     if (((SPObjectClass *) feDisplacementMap_parent_class)->write) {
         ((SPObjectClass *) feDisplacementMap_parent_class)->write(object, doc, repr, flags);
     }
index 003d174c1fe8b6c48ffe8b11df9275c330451762..625e35d42bf765183611c38561bbe824d25e3258 100644 (file)
@@ -179,14 +179,10 @@ sp_feFlood_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feFlood_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 *) feFlood_parent_class)->write) {
index 1c92b772a43f6c56817065b951367b831c5c01d0..0002ef94c74a36b336aa2e40350a2027e5266fd3 100644 (file)
@@ -241,14 +241,10 @@ sp_feImage_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feImage_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 *) feImage_parent_class)->write) {
index a1f17889dcdf9e6f48246dbc6905cf464956ae4f..437cb4b5511caf21724301aa24594a4dca167020 100644 (file)
@@ -147,16 +147,13 @@ sp_feMerge_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feMerge_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. And child nodes, too! */
+    if (!repr) {
+        repr = SP_OBJECT_REPR(object)->duplicate(doc);
     }
 
+
     if (((SPObjectClass *) feMerge_parent_class)->write) {
         ((SPObjectClass *) feMerge_parent_class)->write(object, doc, repr, flags);
     }
index 679221626efd6f1317fef4d1ec470f995d5c3e87..9a34bbccba3634a472dd93a342099160608ecdf6 100644 (file)
@@ -182,14 +182,10 @@ sp_feMorphology_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feMorphology_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 *) feMorphology_parent_class)->write) {
index 2bfeb4a1f69164c17dd834ed0ad3b791690a5c9e..61ea45ff2a5549b1f1cf365b9af41e46719f1970 100644 (file)
@@ -166,15 +166,10 @@ sp_feOffset_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feOffset_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?
-            // Not. Causes coredumps.
-            // 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 *) feOffset_parent_class)->write) {
index 4c73033e604ccb05d8ea104ac7755742f5b8cb6a..03a0c7f9687d2f844ed4629086c4f7ed8c1d586e 100644 (file)
@@ -270,15 +270,13 @@ sp_feSpecularLighting_write(SPObject *object, Inkscape::XML::Document *doc, Inks
 {
     SPFeSpecularLighting *fespecularlighting = SP_FESPECULARLIGHTING(object);
     
-    // 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 _and children_ into it */
+    if (!repr) {
+        repr = SP_OBJECT_REPR(object)->duplicate(doc);
+        //repr = doc->createElement("svg:feSpecularLighting");
     }
+
     if (fespecularlighting->surfaceScale_set)
         sp_repr_set_css_double(repr, "surfaceScale", fespecularlighting->surfaceScale);
     if (fespecularlighting->specularConstant_set)
index cf72cb0527d63a1d3cac6dcf4a5ad39528e9be27..877f70b27d0f72223a1cd83a8c7217c27001d02d 100644 (file)
@@ -147,14 +147,10 @@ sp_feTile_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feTile_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 *) feTile_parent_class)->write) {
index 503f4488b01aec1a68e04b339b8989d51fa80a08..f3c1430565863e1e7882517b0bbd2a3c5c357005 100644 (file)
@@ -232,20 +232,19 @@ sp_feTurbulence_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_feTurbulence_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 *) feTurbulence_parent_class)->write) {
         ((SPObjectClass *) feTurbulence_parent_class)->write(object, doc, repr, flags);
     }
 
+    /* turbulence doesn't take input */
+    repr->setAttribute("in", 0);
+
     return repr;
 }
 
index 9bfaff4aa6751dfc7ca94d56cd7a84f41400fb5d..77325c4b11fa9041d2b79ccd8857e167aaff569d 100644 (file)
@@ -179,18 +179,19 @@ sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_filter_primitive_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
 {
-    //SPFilterPrimitive *filterPrimitive = SP_FILTER_PRIMITIVE(object);
+    SPFilterPrimitive *prim = SP_FILTER_PRIMITIVE(object);
+    SPFilter *parent = SP_FILTER(object->parent);
 
-    // 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);
-        }
+    if (!repr) {
+        repr = SP_OBJECT_REPR(object)->duplicate(doc);
     }
 
+    gchar const *in_name = sp_filter_name_for_image(parent, prim->image_in);
+    repr->setAttribute("in", in_name);
+
+    gchar const *out_name = sp_filter_name_for_image(parent, prim->image_out);
+    repr->setAttribute("result", out_name);
+
     if (((SPObjectClass *) filter_primitive_parent_class)->write) {
         ((SPObjectClass *) filter_primitive_parent_class)->write(object, doc, repr, flags);
     }
@@ -242,6 +243,31 @@ int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name)
     return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET;
 }
 
+/**
+ * Gives name for output of previous filter. Makes things clearer when prim
+ * is a filter with two or more inputs. Returns the slot number of result
+ * of previous primitive, or NR_FILTER_SOURCEGRAPHIC if this is the first
+ * primitive.
+ */
+int sp_filter_primitive_name_previous_out(SPFilterPrimitive *prim) {
+    SPFilter *parent = SP_FILTER(prim->parent);
+    SPObject *i = parent->children;
+    while (i && i->next != prim) i = i->next;
+    if (i) {
+        SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
+        if (i_prim->image_out < 0) {
+            Glib::ustring name = sp_filter_get_new_result_name(parent);
+            int slot = sp_filter_set_image_name(parent, name.c_str());
+            i_prim->image_out = slot;
+            i_prim->repr->setAttribute("result", name.c_str());
+            return slot;
+        } else {
+            return i_prim->image_out;
+        }
+    }
+    return Inkscape::Filters::NR_FILTER_SOURCEGRAPHIC;
+}
+
 /* Common initialization for filter primitives */
 void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, Inkscape::Filters::FilterPrimitive *nr_prim)
 {
index 889c40e40b4ea08774811f05d17de4c60b5b0540..3a7e738617a6179f042cd12b0183e41f30828fbb 100644 (file)
@@ -42,6 +42,7 @@ GType sp_filter_primitive_get_type (void);
 /* Common initialization for filter primitives */
 void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, Inkscape::Filters::FilterPrimitive *nr_prim);
 
+int sp_filter_primitive_name_previous_out(SPFilterPrimitive *prim);
 int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name);
 int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name);
 
index db27e182689cb14601bbef88ab7d84071dda5fa8..7197c1ec93539c53810f0d0db80ac58703a24882 100644 (file)
@@ -284,9 +284,29 @@ static Inkscape::XML::Node *
 sp_filter_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
 {
     SPFilter *filter = SP_FILTER(object);
-
-    if (!repr) {
-        repr = SP_OBJECT_REPR(object)->duplicate(doc);
+    SPObject *child;
+    Inkscape::XML::Node *crepr;
+
+    /* Original from sp-item-group.cpp */
+    if (flags & SP_OBJECT_WRITE_BUILD) {
+        GSList *l;
+        if (!repr) {
+            repr = doc->createElement("svg:filter");
+        }
+        l = NULL;
+        for (child = sp_object_first_child(object); child != NULL; child = SP_OBJECT_NEXT(child) ) {
+            crepr = child->updateRepr(doc, NULL, flags);
+            if (crepr) l = g_slist_prepend (l, crepr);
+        }
+        while (l) {
+            repr->addChild((Inkscape::XML::Node *) l->data, NULL);
+            Inkscape::GC::release((Inkscape::XML::Node *) l->data);
+            l = g_slist_remove (l, l->data);
+        }
+    } else {
+        for (child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+            child->updateRepr(flags);
+        }
     }
 
     if ((flags & SP_OBJECT_WRITE_ALL) || filter->filterUnits_set) {
@@ -488,6 +508,42 @@ int sp_filter_set_image_name(SPFilter *filter, gchar const *name) {
     return value;
 }
 
+gchar const *sp_filter_name_for_image(SPFilter const *filter, int const image) {
+    switch (image) {
+        case Inkscape::Filters::NR_FILTER_SOURCEGRAPHIC:
+            return "SourceGraphic";
+            break;
+        case Inkscape::Filters::NR_FILTER_SOURCEALPHA:
+            return "SourceAlpha";
+            break;
+        case Inkscape::Filters::NR_FILTER_BACKGROUNDIMAGE:
+            return "BackgroundImage";
+            break;
+        case Inkscape::Filters::NR_FILTER_BACKGROUNDALPHA:
+            return "BackgroundAlpha";
+            break;
+        case Inkscape::Filters::NR_FILTER_STROKEPAINT:
+            return "StrokePaint";
+            break;
+        case Inkscape::Filters::NR_FILTER_FILLPAINT:
+            return "FillPaint";
+            break;
+        case Inkscape::Filters::NR_FILTER_SLOT_NOT_SET:
+        case Inkscape::Filters::NR_FILTER_UNNAMED_SLOT:
+            return 0;
+            break;
+        default:
+            for (map<gchar *, int, ltstr>::const_iterator i
+                     = filter->_image_name->begin() ;
+                 i != filter->_image_name->end() ; i++) {
+                if (i->second == image) {
+                    return i->first;
+                }
+            }
+    }
+    return 0;
+}
+
 Glib::ustring sp_filter_get_new_result_name(SPFilter *filter) {
     g_assert(filter != NULL);
     int largest = 0;
index c1af5f768728385b5e8e9756cfe32094482aea73..5ad3863e5abd5b17272882b2be4d570ac9f7931b 100644 (file)
@@ -81,8 +81,19 @@ void sp_filter_build_renderer(SPFilter *sp_filter, Inkscape::Filters::Filter *nr
  */
 int sp_filter_primitive_count(SPFilter *filter);
 
+/**
+ * Returns a slot number for given image name, or -1 for unknown name.
+ */
 int sp_filter_get_image_name(SPFilter *filter, gchar const *name);
+/**
+ * Returns slot number for given image name, even if it's unknown.
+ */
 int sp_filter_set_image_name(SPFilter *filter, gchar const *name);
+/**
+ * Finds image name based on it's slot number. Returns 0 for unknown slot
+ * numbers.
+ */
+gchar const *sp_filter_name_for_image(SPFilter const *filter, int const image);
 
 /*
  * Returns a result image name that is not in use inside this filter.
index 77efe9c01f5f5d4e7c2048fa879af023262f6d43..e6eab5032264c454b762b7029d827e2c2bf4b719 100644 (file)
@@ -157,15 +157,10 @@ sp_gaussianBlur_update(SPObject *object, SPCtx *ctx, guint flags)
 static Inkscape::XML::Node *
 sp_gaussianBlur_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); // FIXME
-        }
+    /* 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 *) gaussianBlur_parent_class)->write) {