From: kiirala Date: Sun, 17 May 2009 21:43:43 +0000 (+0000) Subject: Fixed several cases of bad SVG being written from filters X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=ce31c2a2937dddb2eb4fd13b2cf8679882038d29;p=inkscape.git Fixed several cases of bad SVG being written from filters --- diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index 709130ada..5998d7be3 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -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); } diff --git a/src/filters/colormatrix.cpp b/src/filters/colormatrix.cpp index a6096bdb6..55cfcbeb7 100644 --- a/src/filters/colormatrix.cpp +++ b/src/filters/colormatrix.cpp @@ -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) { diff --git a/src/filters/componenttransfer.cpp b/src/filters/componenttransfer.cpp index f2f68e05d..557d884e0 100644 --- a/src/filters/componenttransfer.cpp +++ b/src/filters/componenttransfer.cpp @@ -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) { diff --git a/src/filters/composite.cpp b/src/filters/composite.cpp index 75ee0fd27..93c692f94 100644 --- a/src/filters/composite.cpp +++ b/src/filters/composite.cpp @@ -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); } diff --git a/src/filters/convolvematrix.cpp b/src/filters/convolvematrix.cpp index 5cda2a139..3e1c36f0a 100644 --- a/src/filters/convolvematrix.cpp +++ b/src/filters/convolvematrix.cpp @@ -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); } diff --git a/src/filters/diffuselighting.cpp b/src/filters/diffuselighting.cpp index 9c68006ed..bdc569083 100644 --- a/src/filters/diffuselighting.cpp +++ b/src/filters/diffuselighting.cpp @@ -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) diff --git a/src/filters/displacementmap.cpp b/src/filters/displacementmap.cpp index 047ee4636..baa17d785 100644 --- a/src/filters/displacementmap.cpp +++ b/src/filters/displacementmap.cpp @@ -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); } diff --git a/src/filters/flood.cpp b/src/filters/flood.cpp index 003d174c1..625e35d42 100644 --- a/src/filters/flood.cpp +++ b/src/filters/flood.cpp @@ -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) { diff --git a/src/filters/image.cpp b/src/filters/image.cpp index 1c92b772a..0002ef94c 100644 --- a/src/filters/image.cpp +++ b/src/filters/image.cpp @@ -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) { diff --git a/src/filters/merge.cpp b/src/filters/merge.cpp index a1f17889d..437cb4b55 100644 --- a/src/filters/merge.cpp +++ b/src/filters/merge.cpp @@ -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); } diff --git a/src/filters/morphology.cpp b/src/filters/morphology.cpp index 679221626..9a34bbccb 100644 --- a/src/filters/morphology.cpp +++ b/src/filters/morphology.cpp @@ -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) { diff --git a/src/filters/offset.cpp b/src/filters/offset.cpp index 2bfeb4a1f..61ea45ff2 100644 --- a/src/filters/offset.cpp +++ b/src/filters/offset.cpp @@ -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) { diff --git a/src/filters/specularlighting.cpp b/src/filters/specularlighting.cpp index 4c73033e6..03a0c7f96 100644 --- a/src/filters/specularlighting.cpp +++ b/src/filters/specularlighting.cpp @@ -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) diff --git a/src/filters/tile.cpp b/src/filters/tile.cpp index cf72cb052..877f70b27 100644 --- a/src/filters/tile.cpp +++ b/src/filters/tile.cpp @@ -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) { diff --git a/src/filters/turbulence.cpp b/src/filters/turbulence.cpp index 503f4488b..f3c143056 100644 --- a/src/filters/turbulence.cpp +++ b/src/filters/turbulence.cpp @@ -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; } diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 9bfaff4aa..77325c4b1 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -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) { diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index 889c40e40..3a7e73861 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -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); diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index db27e1826..7197c1ec9 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -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::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; diff --git a/src/sp-filter.h b/src/sp-filter.h index c1af5f768..5ad3863e5 100644 --- a/src/sp-filter.h +++ b/src/sp-filter.h @@ -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. diff --git a/src/sp-gaussian-blur.cpp b/src/sp-gaussian-blur.cpp index 77efe9c01..e6eab5032 100644 --- a/src/sp-gaussian-blur.cpp +++ b/src/sp-gaussian-blur.cpp @@ -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) {