Code

get rid of sp_repr_document_root and (commented) sp_repr_duplicate
[inkscape.git] / src / extension / internal / svg.cpp
1 /*
2  * This is the code that moves all of the SVG loading and saving into
3  * the module format.  Really Inkscape is built to handle these formats
4  * internally, so this is just calling those internal functions.
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   Ted Gould <ted@gould.cx>
9  *
10  * Copyright (C) 2002-2003 Authors
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
18 #include "sp-object.h"
19 #include "svg.h"
20 #include "file.h"
21 #include "extension/system.h"
22 #include "extension/output.h"
23 #include <vector>
25 #ifdef WITH_GNOME_VFS
26 # include <libgnomevfs/gnome-vfs.h>
27 #endif
29 namespace Inkscape {
30 namespace Extension {
31 namespace Internal {
33 #include "clear-n_.h"
35 /**
36     \return   None
37     \brief    What would an SVG editor be without loading/saving SVG
38               files.  This function sets that up.
40     For each module there is a call to Inkscape::Extension::build_from_mem
41     with a rather large XML file passed in.  This is a constant string
42     that describes the module.  At the end of this call a module is
43     returned that is basically filled out.  The one thing that it doesn't
44     have is the key function for the operation.  And that is linked at
45     the end of each call.
46 */
47 void
48 Svg::init(void)
49 {
50     Inkscape::Extension::Extension * ext;
52     /* SVG in */
53     ext = Inkscape::Extension::build_from_mem(
54         "<inkscape-extension>\n"
55             "<name>" N_("SVG Input") "</name>\n"
56             "<id>" SP_MODULE_KEY_INPUT_SVG "</id>\n"
57             "<input>\n"
58                 "<extension>.svg</extension>\n"
59                 "<mimetype>image/x-svg</mimetype>\n"
60                 "<filetypename>" N_("Scalable Vector Graphic (*.svg)") "</filetypename>\n"
61                 "<filetypetooltip>" N_("Inkscape native file format and W3C standard") "</filetypetooltip>\n"
62                 "<output_extension>" SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE "</output_extension>\n"
63             "</input>\n"
64         "</inkscape-extension>", new Svg());
66     /* SVG out Inkscape */
67     ext = Inkscape::Extension::build_from_mem(
68         "<inkscape-extension>\n"
69             "<name>" N_("SVG Output Inkscape") "</name>\n"
70             "<id>" SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE "</id>\n"
71             "<output>\n"
72                 "<extension>.svg</extension>\n"
73                 "<mimetype>image/x-svg</mimetype>\n"
74                 "<filetypename>" N_("Inkscape SVG (*.svg)") "</filetypename>\n"
75                 "<filetypetooltip>" N_("SVG format with Inkscape extensions") "</filetypetooltip>\n"
76                 "<dataloss>FALSE</dataloss>\n"
77             "</output>\n"
78         "</inkscape-extension>", new Svg());
80     /* SVG out */
81     ext = Inkscape::Extension::build_from_mem(
82         "<inkscape-extension>\n"
83             "<name>" N_("SVG Output") "</name>\n"
84             "<id>" SP_MODULE_KEY_OUTPUT_SVG "</id>\n"
85             "<output>\n"
86                 "<extension>.svg</extension>\n"
87                 "<mimetype>image/x-svg</mimetype>\n"
88                 "<filetypename>" N_("Plain SVG (*.svg)") "</filetypename>\n"
89                 "<filetypetooltip>" N_("Scalable Vector Graphics format as defined by the W3C") "</filetypetooltip>\n"
90             "</output>\n"
91         "</inkscape-extension>", new Svg());
93 #ifdef WITH_GNOME_VFS
94     gnome_vfs_init();
95 #endif
98     return;
99 }
102 #ifdef WITH_GNOME_VFS
103 #define BUF_SIZE 8192
105 gchar *
106 _load_uri (const gchar *uri)
108     GnomeVFSHandle   *handle = NULL;
109     GnomeVFSFileSize  bytes_read;
111         gsize bytesRead = 0;
112         gsize bytesWritten = 0;
113         GError* error = NULL;
114         gchar* uri_local = g_filename_from_utf8( uri, -1, &bytesRead, &bytesWritten, &error);
116         if ( uri_local == NULL ) {
117             g_warning( "Error converting filename to locale encoding.");
118         }
120     GnomeVFSResult result = gnome_vfs_open (&handle, uri_local, GNOME_VFS_OPEN_READ);
122     if (result != GNOME_VFS_OK) {
123         g_warning(gnome_vfs_result_to_string(result));
124     }
126     std::vector<gchar> doc;
127     while (result == GNOME_VFS_OK) {
128         gchar buffer[BUF_SIZE];
129         result = gnome_vfs_read (handle, buffer, BUF_SIZE, &bytes_read);
130         doc.insert(doc.end(), buffer, buffer+bytes_read);
131     }
133     return g_strndup(&doc[0], doc.size());
135 #endif
138 /**
139     \return    A new document just for you!
140     \brief     This function takes in a filename of a SVG document and
141                turns it into a SPDocument.
142     \param     mod   Module to use
143     \param     uri   The path to the file (UTF-8)
145     This function is really simple, it just calls sp_document_new...
146 */
147 SPDocument *
148 Svg::open (Inkscape::Extension::Input *mod, const gchar *uri)
150 #ifdef WITH_GNOME_VFS
151     if (gnome_vfs_uri_is_local(gnome_vfs_uri_new(uri))) {
152         // Use built-in loader instead of VFS for this
153         return sp_document_new(uri, TRUE);
154     }
155     gchar * buffer = _load_uri(uri);
156     if (buffer == NULL) {
157         g_warning("Error:  Could not open file '%s' with VFS\n", uri);
158         return NULL;
159     }
160     SPDocument * doc = sp_document_new_from_mem(buffer, strlen(buffer), 1);
161     
162     g_free(buffer);
163     return doc;
164 #else
165     return sp_document_new (uri, TRUE);
166 #endif
169 /**
170     \return    None
171     \brief     This is the function that does all of the SVG saves in
172                Inkscape.  It detects whether it should do a Inkscape
173                namespace save internally.
174     \param     mod   Extension to use.
175     \param     doc   Document to save.
176     \param     uri   The filename to save the file to.
178     This function first checks it's parameters, and makes sure that
179     we're getting good data.  It also checks the module ID of the
180     incoming module to figure out if this is save should include
181     the Inkscape namespace stuff or not.  The result of that comparison
182     is stored in the spns variable.
184     If there is not to be Inkscape name spaces a new document is created
185     without.  (I think, I'm not sure on this code)
187     All of the internally referenced imageins are also set to relative
188     paths in the file.  And the file is saved.
190     This really needs to be fleshed out more, but I don't quite understand
191     all of this code.  I just stole it.
192 */
193 void
194 Svg::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri)
196     g_return_if_fail(doc != NULL);
197     g_return_if_fail(uri != NULL);
199     gchar *save_path = g_path_get_dirname (uri);
201     gboolean const spns = (!mod->get_id() 
202       || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)
203       || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE));
205     Inkscape::XML::Document *rdoc = NULL;
206     Inkscape::XML::Node *repr = NULL;
207     if (spns) {
208         repr = sp_document_repr_root (doc);
209     } else {
210         rdoc = sp_repr_document_new ("svg:svg");
211         repr = rdoc->root();
212         repr = sp_document_root (doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
213     }
215     Inkscape::IO::fixupHrefs( doc, save_path, spns );
217     gboolean const s = sp_repr_save_file (repr->document(), uri, SP_SVG_NS_URI);
218     if (s == FALSE) {
219         throw Inkscape::Extension::Output::save_failed();
220     }
222     if (!spns) {
223         Inkscape::GC::release(rdoc);
224     }
226     g_free(save_path);
228     return;
231 } } }  /* namespace inkscape, module, implementation */
233 /*
234   Local Variables:
235   mode:c++
236   c-file-style:"stroustrup"
237   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
238   indent-tabs-mode:nil
239   fill-column:99
240   End:
241 */
242 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :