e87290ab4dfb752f5d1966e7b2d55cad01ba961c
1 /*
2 * Authors:
3 * Ted Gould <ted@gould.cx>
4 *
5 * Copyright (C) 2008 Authors
6 *
7 * Released under GNU GPL, read the file 'COPYING' for more information
8 */
10 #include "desktop.h"
11 #include "selection.h"
12 #include "document-private.h"
13 #include "sp-item.h"
14 #include "util/glib-list-iterators.h"
15 #include "extension/extension.h"
16 #include "extension/effect.h"
17 #include "extension/system.h"
18 #include "xml/repr.h"
19 #include "xml/simple-node.h"
20 #include "xml/attribute-record.h"
22 #include "filter.h"
24 namespace Inkscape {
25 namespace Extension {
26 namespace Internal {
27 namespace Filter {
29 Filter::Filter() :
30 Inkscape::Extension::Implementation::Implementation(),
31 _filter(NULL) {
32 return;
33 }
35 Filter::Filter(gchar const * filter) :
36 Inkscape::Extension::Implementation::Implementation(),
37 _filter(filter) {
38 return;
39 }
41 Filter::~Filter (void) {
42 if (_filter != NULL) {
43 _filter = NULL;
44 }
46 return;
47 }
49 bool
50 Filter::load (Inkscape::Extension::Extension *module)
51 {
52 return true;
53 }
55 Inkscape::Extension::Implementation::ImplementationDocumentCache *
56 Filter::newDocCache (Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * doc)
57 {
58 return NULL;
59 }
61 gchar const *
62 Filter::get_filter_text (Inkscape::Extension::Extension * ext)
63 {
64 return _filter;
65 }
67 Inkscape::XML::Document *
68 Filter::get_filter (Inkscape::Extension::Extension * ext) {
69 gchar const * filter = get_filter_text(ext);
70 return sp_repr_read_mem(filter, strlen(filter), NULL);
71 }
73 void
74 Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc)
75 {
76 if (from == NULL) return;
78 // copy attributes
79 for ( Inkscape::Util::List<Inkscape::XML::AttributeRecord const> iter = from->attributeList() ;
80 iter ; ++iter ) {
81 gchar const * attr = g_quark_to_string(iter->key);
82 //printf("Attribute List: %s\n", attr);
83 if (!strcmp(attr, "id")) continue; // nope, don't copy that one!
84 to->setAttribute(attr, from->attribute(attr));
85 }
87 // for each child call recursively
88 for (Inkscape::XML::Node * from_child = from->firstChild();
89 from_child != NULL ; from_child = from_child->next()) {
90 Glib::ustring name = "svg:";
91 name += from_child->name();
93 Inkscape::XML::Node * to_child = doc->createElement(name.c_str());
94 to->appendChild(to_child);
95 merge_filters(to_child, from_child, doc);
96 }
98 return;
99 }
101 void
102 Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache)
103 {
104 //printf("Calling filter effect\n");
105 Inkscape::Selection * selection = ((SPDesktop *)document)->selection;
107 using Inkscape::Util::GSListConstIterator;
108 // TODO need to properly refcount the items, at least
109 std::list<SPItem *> items;
110 items.insert<GSListConstIterator<SPItem *> >(items.end(), selection->itemList(), NULL);
112 Inkscape::XML::Document * xmldoc = sp_document_repr_doc(document->doc());
113 Inkscape::XML::Node * defsrepr = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(document->doc()));
115 for(std::list<SPItem *>::iterator item = items.begin();
116 item != items.end(); item++) {
117 SPItem * spitem = *item;
118 Inkscape::XML::Node * node = SP_OBJECT_REPR(spitem);
120 SPCSSAttr * css = sp_repr_css_attr(node, "style");
121 gchar const * filter = sp_repr_css_property(css, "filter", NULL);
123 if (filter == NULL) {
124 Inkscape::XML::Node * newfilterroot = xmldoc->createElement("svg:filter");
125 defsrepr->appendChild(newfilterroot);
126 Glib::ustring url = "url(#"; url += newfilterroot->attribute("id"); url += ")";
128 merge_filters(newfilterroot, get_filter(module)->root(), xmldoc);
130 sp_repr_css_set_property(css, "filter", url.c_str());
131 sp_repr_css_set(node, css, "style");
132 }
133 }
135 return;
136 }
138 #include "extension/internal/clear-n_.h"
140 void
141 Filter::filter_init (gchar const * id, gchar const * name, gchar const * tip, gchar const * filter)
142 {
143 gchar * xml_str = g_strdup_printf(
144 "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
145 "<name>%s</name>\n"
146 "<id>org.inkscape.effect.filter.%s</id>\n"
147 "<effect>\n"
148 "<object-type>all</object-type>\n"
149 "<effects-menu>\n"
150 "<submenu name=\"" N_("Filter") "\" />\n"
151 "</effects-menu>\n"
152 "<menu-tip>%s</menu-tip>\n"
153 "</effect>\n"
154 "</inkscape-extension>\n", name, id, tip);
155 Inkscape::Extension::build_from_mem(xml_str, new Filter::Filter(filter));
156 g_free(xml_str);
157 return;
158 }
160 }; /* namespace Filter */
161 }; /* namespace Internal */
162 }; /* namespace Extension */
163 }; /* namespace Inkscape */