Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / filters / displacementmap.cpp
index 405922b46a706bf99e48cffa1cc4ce761d6223db..956719d10c909bdc91d58a5bc86bb0cdbf5aed7f 100644 (file)
@@ -33,7 +33,7 @@ static void sp_feDisplacementMap_build(SPObject *object, SPDocument *document, I
 static void sp_feDisplacementMap_release(SPObject *object);
 static void sp_feDisplacementMap_set(SPObject *object, unsigned int key, gchar const *value);
 static void sp_feDisplacementMap_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_feDisplacementMap_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter);
+static void sp_feDisplacementMap_build_renderer(SPFilterPrimitive *primitive, Inkscape::Filters::Filter *filter);
 static Inkscape::XML::Node *sp_feDisplacementMap_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
 
 static SPFilterPrimitiveClass *feDisplacementMap_parent_class;
@@ -81,7 +81,7 @@ sp_feDisplacementMap_init(SPFeDisplacementMap *feDisplacementMap)
     feDisplacementMap->scale=0;
     feDisplacementMap->xChannelSelector = DISPLACEMENTMAP_CHANNEL_ALPHA;
     feDisplacementMap->yChannelSelector = DISPLACEMENTMAP_CHANNEL_ALPHA;
-    feDisplacementMap->in2 = NR::NR_FILTER_SLOT_NOT_SET;
+    feDisplacementMap->in2 = Inkscape::Filters::NR_FILTER_SLOT_NOT_SET;
 }
 
 /**
@@ -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));
+    }
 }
 
 /**
@@ -165,7 +176,7 @@ sp_feDisplacementMap_set(SPObject *object, unsigned int key, gchar const *value)
             }
             break;
         case SP_ATTR_SCALE:
-            read_num = helperfns_read_number(value);
+            read_num = value ? helperfns_read_number(value) : 0;
             if (read_num != feDisplacementMap->scale) {
                 feDisplacementMap->scale = read_num;
                 object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -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);
     }
@@ -227,15 +281,15 @@ sp_feDisplacementMap_write(SPObject *object, Inkscape::XML::Document *doc, Inksc
     return repr;
 }
 
-static void sp_feDisplacementMap_build_renderer(SPFilterPrimitive *primitive, NR::Filter *filter) {
+static void sp_feDisplacementMap_build_renderer(SPFilterPrimitive *primitive, Inkscape::Filters::Filter *filter) {
     g_assert(primitive != NULL);
     g_assert(filter != NULL);
 
     SPFeDisplacementMap *sp_displacement_map = SP_FEDISPLACEMENTMAP(primitive);
 
-    int primitive_n = filter->add_primitive(NR::NR_FILTER_DISPLACEMENTMAP);
-    NR::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
-    NR::FilterDisplacementMap *nr_displacement_map = dynamic_cast<NR::FilterDisplacementMap*>(nr_primitive);
+    int primitive_n = filter->add_primitive(Inkscape::Filters::NR_FILTER_DISPLACEMENTMAP);
+    Inkscape::Filters::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
+    Inkscape::Filters::FilterDisplacementMap *nr_displacement_map = dynamic_cast<Inkscape::Filters::FilterDisplacementMap*>(nr_primitive);
     g_assert(nr_displacement_map != NULL);
 
     sp_filter_primitive_renderer_common(primitive, nr_primitive);
@@ -256,4 +310,4 @@ static void sp_feDisplacementMap_build_renderer(SPFilterPrimitive *primitive, NR
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :