diff options
| author | MenTaLguY <mental@rydia.net> | 2006-01-16 02:36:01 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2006-01-16 02:36:01 +0000 |
| commit | 179fa413b047bede6e32109e2ce82437c5fb8d34 (patch) | |
| tree | a5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/extension/internal/svg.cpp | |
| download | inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip | |
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/extension/internal/svg.cpp')
| -rw-r--r-- | src/extension/internal/svg.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp new file mode 100644 index 000000000..e6d02b62d --- /dev/null +++ b/src/extension/internal/svg.cpp @@ -0,0 +1,248 @@ +/* + * This is the code that moves all of the SVG loading and saving into + * the module format. Really Inkscape is built to handle these formats + * internally, so this is just calling those internal functions. + * + * Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * Ted Gould <ted@gould.cx> + * + * Copyright (C) 2002-2003 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include "sp-object.h" +#include "svg.h" +#include "file.h" +#include "extension/system.h" +#include "extension/output.h" + +#ifdef WITH_GNOME_VFS +# include <libgnomevfs/gnome-vfs.h> +#endif + +namespace Inkscape { +namespace Extension { +namespace Internal { + +/** + \return None + \brief What would an SVG editor be without loading/saving SVG + files. This function sets that up. + + For each module there is a call to Inkscape::Extension::build_from_mem + with a rather large XML file passed in. This is a constant string + that describes the module. At the end of this call a module is + returned that is basically filled out. The one thing that it doesn't + have is the key function for the operation. And that is linked at + the end of each call. +*/ +void +Svg::init(void) +{ + Inkscape::Extension::Extension * ext; + + /* SVG in */ + ext = Inkscape::Extension::build_from_mem( + "<inkscape-extension>\n" + "<name>SVG Input</name>\n" + "<id>" SP_MODULE_KEY_INPUT_SVG "</id>\n" + "<input>\n" + "<extension>.svg</extension>\n" + "<mimetype>image/x-svg</mimetype>\n" + "<filetypename>Scalable Vector Graphic (*.svg)</filetypename>\n" + "<filetypetooltip>Inkscape native file format and W3C standard</filetypetooltip>\n" + "<output_extension>" SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE "</output_extension>\n" + "</input>\n" + "</inkscape-extension>", new Svg()); + + /* SVG out Inkscape */ + ext = Inkscape::Extension::build_from_mem( + "<inkscape-extension>\n" + "<name>SVG Output Inkscape</name>\n" + "<id>" SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE "</id>\n" + "<output>\n" + "<extension>.svg</extension>\n" + "<mimetype>image/x-svg</mimetype>\n" + "<filetypename>Inkscape SVG (*.svg)</filetypename>\n" + "<filetypetooltip>SVG format with Inkscape extensions</filetypetooltip>\n" + "<dataloss>FALSE</dataloss>\n" + "</output>\n" + "</inkscape-extension>", new Svg()); + + /* SVG out */ + ext = Inkscape::Extension::build_from_mem( + "<inkscape-extension>\n" + "<name>SVG Output</name>\n" + "<id>" SP_MODULE_KEY_OUTPUT_SVG "</id>\n" + "<output>\n" + "<extension>.svg</extension>\n" + "<mimetype>image/x-svg</mimetype>\n" + "<filetypename>Plain SVG (*.svg)</filetypename>\n" + "<filetypetooltip>Scalable Vector Graphics format as defined by the W3C</filetypetooltip>\n" + "</output>\n" + "</inkscape-extension>", new Svg()); + +#ifdef WITH_GNOME_VFS + gnome_vfs_init(); +#endif + + + return; +} + + +#ifdef WITH_GNOME_VFS +#define BUF_SIZE 8192 + +gchar * +_load_uri (const gchar *uri) +{ + GnomeVFSHandle *handle = NULL; + GnomeVFSFileSize bytes_read; + gchar buffer[BUF_SIZE] = ""; + gchar *doc = NULL; + gchar *new_doc = NULL; + + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError* error = NULL; + gchar* uri_local = g_filename_from_utf8( uri, -1, &bytesRead, &bytesWritten, &error); + + if ( uri_local == NULL ) { + g_warning( "Error converting filename to locale encoding."); + } + + GnomeVFSResult result = gnome_vfs_open (&handle, uri_local, GNOME_VFS_OPEN_READ); + + if (result != GNOME_VFS_OK) { + g_warning(gnome_vfs_result_to_string(result)); + } + + while (result == GNOME_VFS_OK) { + result = gnome_vfs_read (handle, buffer, BUF_SIZE, &bytes_read); + buffer[bytes_read] = '\0'; + + if (doc == NULL) { + doc = g_strndup(buffer, bytes_read); + } else { + new_doc = g_strconcat(doc, buffer, NULL); + g_free(doc); + doc = new_doc; + } + } + + return doc; +} +#endif + + +/** + \return A new document just for you! + \brief This function takes in a filename of a SVG document and + turns it into a SPDocument. + \param mod Module to use + \param uri The path to the file (UTF-8) + + This function is really simple, it just calls sp_document_new... +*/ +SPDocument * +Svg::open (Inkscape::Extension::Input *mod, const gchar *uri) +{ +#ifdef WITH_GNOME_VFS + if (gnome_vfs_uri_is_local(gnome_vfs_uri_new(uri))) { + // Use built-in loader instead of VFS for this + return sp_document_new(uri, TRUE); + } + gchar * buffer = _load_uri(uri); + if (buffer == NULL) { + g_warning("Error: Could not open file '%s' with VFS\n", uri); + return NULL; + } + SPDocument * doc = sp_document_new_from_mem(buffer, strlen(buffer), 1); + + g_free(buffer); + return doc; +#else + return sp_document_new (uri, TRUE); +#endif +} + +/** + \return None + \brief This is the function that does all of the SVG saves in + Inkscape. It detects whether it should do a Inkscape + namespace save internally. + \param mod Extension to use. + \param doc Document to save. + \param uri The filename to save the file to. + + This function first checks it's parameters, and makes sure that + we're getting good data. It also checks the module ID of the + incoming module to figure out if this is save should include + the Inkscape namespace stuff or not. The result of that comparison + is stored in the spns variable. + + If there is not to be Inkscape name spaces a new document is created + without. (I think, I'm not sure on this code) + + All of the internally referenced imageins are also set to relative + paths in the file. And the file is saved. + + This really needs to be fleshed out more, but I don't quite understand + all of this code. I just stole it. +*/ +void +Svg::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri) +{ + g_return_if_fail(doc != NULL); + g_return_if_fail(uri != NULL); + + gchar *save_path = g_path_get_dirname (uri); + + gboolean const spns = (!mod->get_id() + || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE) + || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE)); + + Inkscape::XML::Document *rdoc = NULL; + Inkscape::XML::Node *repr = NULL; + if (spns) { + repr = sp_document_repr_root (doc); + } else { + rdoc = sp_repr_document_new ("svg:svg"); + repr = sp_repr_document_root (rdoc); + repr = sp_document_root (doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD); + } + + Inkscape::IO::fixupHrefs( doc, save_path, spns ); + + gboolean const s = sp_repr_save_file (sp_repr_document (repr), uri, SP_SVG_NS_URI); + if (s == FALSE) { + throw Inkscape::Extension::Output::save_failed(); + } + + if (!spns) { + Inkscape::GC::release(rdoc); + } + + g_free(save_path); + + return; +} + +} } } /* namespace inkscape, module, implementation */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
