summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0985026)
raw | patch | inline | side by side (parent: 0985026)
author | gouldtj <gouldtj@users.sourceforge.net> | |
Sat, 26 Apr 2008 04:22:42 +0000 (04:22 +0000) | ||
committer | gouldtj <gouldtj@users.sourceforge.net> | |
Sat, 26 Apr 2008 04:22:42 +0000 (04:22 +0000) |
Basis for reading filters out of SVG files in system and personal directories.
r19137@shi: ted | 2008-04-24 20:45:27 -0700
Removing a TODO
r19138@shi: ted | 2008-04-24 20:55:50 -0700
Filling this out some. Now we're looking through the files and finding
the filters in it.
r19139@shi: ted | 2008-04-24 22:07:55 -0700
Changing to build filename, really amazing that it's worked before.
r19140@shi: ted | 2008-04-24 22:43:57 -0700
My own crazy writer. Output streams are stupid C++-isms. char * works just fine.
r19154@shi: ted | 2008-04-24 22:56:05 -0700
Cleaning up the XML transfer. Pretty happy with it now.
r19155@shi: ted | 2008-04-24 23:00:11 -0700
Don't need to set up that string for translation because it's getting
placed inside a structure that gets thrown gettext already.
r19156@shi: ted | 2008-04-25 17:12:40 -0700
OMG! Stacking seems to be working. Now it's very easy to test the cooling on your CPU using Inkscape. That's going to have to be a feature in the release notes.
r19166@shi: ted | 2008-04-25 21:00:34 -0700
Adding in filter-file.cpp
r19137@shi: ted | 2008-04-24 20:45:27 -0700
Removing a TODO
r19138@shi: ted | 2008-04-24 20:55:50 -0700
Filling this out some. Now we're looking through the files and finding
the filters in it.
r19139@shi: ted | 2008-04-24 22:07:55 -0700
Changing to build filename, really amazing that it's worked before.
r19140@shi: ted | 2008-04-24 22:43:57 -0700
My own crazy writer. Output streams are stupid C++-isms. char * works just fine.
r19154@shi: ted | 2008-04-24 22:56:05 -0700
Cleaning up the XML transfer. Pretty happy with it now.
r19155@shi: ted | 2008-04-24 23:00:11 -0700
Don't need to set up that string for translation because it's getting
placed inside a structure that gets thrown gettext already.
r19156@shi: ted | 2008-04-25 17:12:40 -0700
OMG! Stacking seems to be working. Now it's very easy to test the cooling on your CPU using Inkscape. That's going to have to be a feature in the release notes.
r19166@shi: ted | 2008-04-25 21:00:34 -0700
Adding in filter-file.cpp
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fd124043f402c62534164e6dbc2b024fc8be2fa7..8f44328c42d0379a0bc9ab4c1a375efbd6c22a63 100644 (file)
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
src/extension/internal/filter/drop-shadow.h
src/extension/internal/filter/etched-glass.h
src/extension/internal/filter/filter.cpp
+src/extension/internal/filter/filter-file.cpp
src/extension/internal/filter/fire.h
src/extension/internal/filter/frost.h
src/extension/internal/filter/ink-bleed.h
diff --git a/src/extension/init.cpp b/src/extension/init.cpp
index a1d88d7ec2e6de6e725cda674fefcb84e438da50..649a654712b8fc9d5dbea2c62760dbc8ed462f86 100644 (file)
--- a/src/extension/init.cpp
+++ b/src/extension/init.cpp
gchar *filename;
while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
-
if (strlen(filename) < strlen(SP_MODULE_EXTENSION)) {
continue;
}
continue;
}
- gchar *pathname = g_strdup_printf("%s/%s", dirname, filename);
+ gchar *pathname = g_build_filename(dirname, filename, NULL);
build_from_file(pathname);
g_free(pathname);
}
g_dir_close(directory);
+
+ return;
}
index bca2b0a6d9dc28fadf3709e72447e24f386e7fc1..73303ffca1b1abdd058fa7d5d2ac029b931fb615 100644 (file)
$(extension_internal_image_magick_sources) \
\
extension/internal/filter/filter-all.cpp \
+ extension/internal/filter/filter-file.cpp \
extension/internal/filter/filter.cpp \
extension/internal/filter/filter.h
diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp
index 917730e2c51c616d5466eee4cfc710c1c954dd9f..08bef9f742e019bba137dc9dc75ba3dc8cc7534d 100644 (file)
Speckle::init();
Zebra::init();
+
+ /* This should always be last, don't put stuff below this
+ * line. */
+ Filter::filters_all_files();
+
return;
}
diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "filter.h"
+
+#include "io/sys.h"
+#include "io/inkscapestream.h"
+
+/* Directory includes */
+#include "path-prefix.h"
+#include "inkscape.h"
+
+/* Extension */
+#include "extension/extension.h"
+#include "extension/system.h"
+
+/* System includes */
+#include <glibmm/i18n.h>
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+void
+Filter::filters_all_files (void)
+{
+ filters_load_dir(INKSCAPE_FILTERDIR, _("Bundled"));
+ filters_load_dir(profile_path("filters"), _("Personal"));
+
+ return;
+}
+
+#define INKSCAPE_FILTER_FILE ".svg"
+
+void
+Filter::filters_load_dir (gchar * dirname, gchar * menuname)
+{
+ if (!dirname) {
+ g_warning(_("Null external module directory name. Filters will not be loaded."));
+ return;
+ }
+
+ if (!Glib::file_test(std::string(dirname), Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_DIR)) {
+ return;
+ }
+
+ GError *err;
+ GDir *directory = g_dir_open(dirname, 0, &err);
+ if (!directory) {
+ gchar *safeDir = Inkscape::IO::sanitizeString(dirname);
+ g_warning(_("Modules directory (%s) is unavailable. External modules in that directory will not be loaded."), safeDir);
+ g_free(safeDir);
+ return;
+ }
+
+ gchar *filename;
+ while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
+ if (strlen(filename) < strlen(INKSCAPE_FILTER_FILE)) {
+ continue;
+ }
+
+ if (strcmp(INKSCAPE_FILTER_FILE, filename + (strlen(filename) - strlen(INKSCAPE_FILTER_FILE)))) {
+ continue;
+ }
+
+ gchar *pathname = g_build_filename(dirname, filename, NULL);
+ filters_load_file(pathname, menuname);
+ g_free(pathname);
+ }
+
+ g_dir_close(directory);
+
+ return;
+}
+
+void
+Filter::filters_load_file (gchar * filename, gchar * menuname)
+{
+ Inkscape::XML::Document *doc = sp_repr_read_file(filename, INKSCAPE_EXTENSION_URI);
+ if (doc == NULL) {
+ g_warning("File (%s) is not parseable as XML. Ignored.", filename);
+ return;
+ }
+
+ Inkscape::XML::Node * root = doc->root();
+ if (strcmp(root->name(), "svg:svg")) {
+ Inkscape::GC::release(doc);
+ g_warning("File (%s) is not SVG. Ignored.", filename);
+ return;
+ }
+
+ for (Inkscape::XML::Node * child = root->firstChild();
+ child != NULL; child = child->next()) {
+ if (!strcmp(child->name(), "svg:defs")) {
+ for (Inkscape::XML::Node * defs = child->firstChild();
+ defs != NULL; defs = defs->next()) {
+ if (!strcmp(defs->name(), "svg:filter")) {
+ filters_load_node(defs, menuname);
+ } // oh! a filter
+ } //defs
+ } // is defs
+ } // children of root
+
+ Inkscape::GC::release(doc);
+ return;
+}
+
+#include "extension/internal/clear-n_.h"
+
+class mywriter : public Inkscape::IO::BasicWriter {
+ Glib::ustring _str;
+public:
+ void close(void);
+ void flush(void);
+ void put (gunichar ch);
+ gchar const * c_str (void) { return _str.c_str(); }
+};
+
+void mywriter::close (void) { return; }
+void mywriter::flush (void) { return; }
+void mywriter::put (gunichar ch) { _str += ch; }
+
+
+void
+Filter::filters_load_node (Inkscape::XML::Node * node, gchar * menuname)
+{
+ gchar const * label = node->attribute("inkscape:label");
+ gchar const * id = node->attribute("id");
+
+ if (label == NULL) {
+ label = id;
+ }
+
+ gchar * xml_str = g_strdup_printf(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>%s</name>\n"
+ "<id>org.inkscape.effect.filter.%s</id>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filter") "\">\n"
+ "<submenu name=\"%s\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", label, id, menuname);
+
+ mywriter writer;
+ sp_repr_write_stream(node, writer, 0, FALSE, g_quark_from_static_string("svg"), 0, 0);
+
+ Inkscape::Extension::build_from_mem(xml_str, new Filter::Filter(g_strdup(writer.c_str())));
+ g_free(xml_str);
+ return;
+}
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
index e87290ab4dfb752f5d1966e7b2d55cad01ba961c..b2a55b6e6154a9c1522378bd133ad66185f32408 100644 (file)
}
void
-Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc)
+Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar * srcGraphic, gchar * srcGraphicAlpha)
{
if (from == NULL) return;
//printf("Attribute List: %s\n", attr);
if (!strcmp(attr, "id")) continue; // nope, don't copy that one!
to->setAttribute(attr, from->attribute(attr));
+
+ if (!strcmp(attr, "in") || !strcmp(attr, "in2") || !strcmp(attr, "in3")) {
+ if (srcGraphic != NULL && !strcmp(from->attribute(attr), "SourceGraphic")) {
+ to->setAttribute(attr, srcGraphic);
+ }
+
+ if (srcGraphicAlpha != NULL && !strcmp(from->attribute(attr), "SourceAlpha")) {
+ to->setAttribute(attr, srcGraphicAlpha);
+ }
+ }
}
// for each child call recursively
@@ -92,12 +102,19 @@ Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Ink
Inkscape::XML::Node * to_child = doc->createElement(name.c_str());
to->appendChild(to_child);
- merge_filters(to_child, from_child, doc);
+ merge_filters(to_child, from_child, doc, srcGraphic, srcGraphicAlpha);
+
+ if (from_child == from->firstChild() && !strcmp("filter", from->name()) && srcGraphic != NULL && to_child->attribute("in") == NULL) {
+ to_child->setAttribute("in", srcGraphic);
+ }
}
return;
}
+#define FILTER_SRC_GRAPHIC "fbSourceGraphic"
+#define FILTER_SRC_GRAPHIC_ALPHA "fbSourceGraphicAlpha"
+
void
Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache)
{
@@ -129,6 +146,35 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d
sp_repr_css_set_property(css, "filter", url.c_str());
sp_repr_css_set(node, css, "style");
+ } else {
+ if (strncmp(filter, "url(#", strlen("url(#")) || filter[strlen(filter) - 1] != ')') {
+ // This is not url(#id) -- we can't handle it
+ continue;
+ }
+
+ gchar * lfilter = g_strndup(filter + 5, strlen(filter) - 6);
+ Inkscape::XML::Node * filternode = NULL;
+ for (Inkscape::XML::Node * child = defsrepr->firstChild(); child != NULL; child = child->next()) {
+ if (!strcmp(lfilter, child->attribute("id"))) {
+ filternode = child;
+ break;
+ }
+ }
+ g_free(lfilter);
+
+ if (filternode == NULL) {
+ continue;
+ }
+
+ filternode->lastChild()->setAttribute("result", FILTER_SRC_GRAPHIC);
+
+ Inkscape::XML::Node * alpha = xmldoc->createElement("svg:feColorMatrix");
+ alpha->setAttribute("result", FILTER_SRC_GRAPHIC_ALPHA);
+ alpha->setAttribute("in", FILTER_SRC_GRAPHIC); // not required, but we're being explicit
+ alpha->setAttribute("values", "0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0");
+ filternode->appendChild(alpha);
+
+ merge_filters(filternode, get_filter(module)->root(), xmldoc, FILTER_SRC_GRAPHIC, FILTER_SRC_GRAPHIC_ALPHA);
}
}
index 851beb833dae5366278bad3588e8f36315d87f5b..28924988de66c001292c5340a480f061de6624b4 100644 (file)
private:
Inkscape::XML::Document * get_filter (Inkscape::Extension::Extension * ext);
- void merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc);
+ void merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar * srcGraphic = NULL, gchar * srcGraphicAlpha = NULL);
public:
Filter();
static void filter_init(gchar const * id, gchar const * name, gchar const * tip, gchar const * filter);
static void filters_all(void);
+
+ /* File loader related */
+ static void filters_all_files(void);
+ static void filters_load_dir(gchar * filename, gchar * menuname);
+ static void filters_load_file(gchar * filename, gchar * menuname);
+ static void filters_load_node(Inkscape::XML::Node * node, gchar * menuname);
+
};
}; /* namespace Filter */
index d66655a511f409ee8ac8f175361bcf33a9aae018..cd70042b6e758d2918956fe0fa2268817a95927c 100644 (file)
--- a/src/extension/system.cpp
+++ b/src/extension/system.cpp
Extension *
build_from_file(gchar const *filename)
{
- /* TODO: Need to define namespace here, need to write the
- DTD in general for this stuff */
Inkscape::XML::Document *doc = sp_repr_read_file(filename, INKSCAPE_EXTENSION_URI);
Extension *ext = build_from_reprdoc(doc, NULL);
if (ext != NULL)
diff --git a/src/path-prefix.h b/src/path-prefix.h
index a6ad95188ff754468e3743035a27813a7a3e8cf3..72c21ca55d84e3c94638aefea388fe13cec07eae 100644 (file)
--- a/src/path-prefix.h
+++ b/src/path-prefix.h
# define INKSCAPE_BINDDIR BR_DATADIR( "/inkscape/bind" )
# define INKSCAPE_EXAMPLESDIR BR_DATADIR( "/inkscape/examples" )
# define INKSCAPE_EXTENSIONDIR BR_DATADIR( "/inkscape/extensions" )
+# define INKSCAPE_FILTERDIR BR_DATADIR( "/inkscape/filters" )
# define INKSCAPE_GRADIENTSDIR BR_DATADIR( "/inkscape/gradients" )
# define INKSCAPE_KEYSDIR BR_DATADIR( "/inkscape/keys" )
# define INKSCAPE_PIXMAPDIR BR_DATADIR( "/inkscape/icons" )
# define INKSCAPE_BINDDIR "share\\bind"
# define INKSCAPE_EXAMPLESDIR "share\\examples"
# define INKSCAPE_EXTENSIONDIR "share\\extensions"
+# define INKSCAPE_FILTERDIR "share\\filters"
# define INKSCAPE_GRADIENTSDIR "share\\gradients"
# define INKSCAPE_KEYSDIR "share\\keys"
# define INKSCAPE_PIXMAPDIR "share\\icons"
# define INKSCAPE_BINDDIR "Contents/Resources/bind"
# define INKSCAPE_EXAMPLESDIR "Contents/Resources/examples"
# define INKSCAPE_EXTENSIONDIR "Contents/Resources/extensions"
+# define INKSCAPE_FILTERDIR "Contents/Resources/filters"
# define INKSCAPE_GRADIENTSDIR "Contents/Resources/gradients"
# define INKSCAPE_KEYSDIR "Contents/Resources/keys"
# define INKSCAPE_PIXMAPDIR "Contents/Resources/icons"
# define INKSCAPE_BINDDIR INKSCAPE_DATADIR "/inkscape/bind"
# define INKSCAPE_EXAMPLESDIR INKSCAPE_DATADIR "/inkscape/examples"
# define INKSCAPE_EXTENSIONDIR INKSCAPE_DATADIR "/inkscape/extensions"
+# define INKSCAPE_FILTERDIR INKSCAPE_DATADIR "/inkscape/filters"
# define INKSCAPE_GRADIENTSDIR INKSCAPE_DATADIR "/inkscape/gradients"
# define INKSCAPE_KEYSDIR INKSCAPE_DATADIR "/inkscape/keys"
# define INKSCAPE_PIXMAPDIR INKSCAPE_DATADIR "/inkscape/icons"