diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2011-05-06 06:21:51 +0000 |
|---|---|---|
| committer | Jon A. Cruz <jon@joncruz.org> | 2011-05-06 06:21:51 +0000 |
| commit | a4d0a358424440128cd4c4fb2915ccc4b86f4587 (patch) | |
| tree | 818fc169950e0076d262bd8e633976afaafd7783 /src/xml | |
| parent | symbol rendering fix bug:705345 (diff) | |
| download | inkscape-a4d0a358424440128cd4c4fb2915ccc4b86f4587.tar.gz inkscape-a4d0a358424440128cd4c4fb2915ccc4b86f4587.zip | |
Adding initial cut of resource manager.
(bzr r10198)
Diffstat (limited to 'src/xml')
| -rw-r--r-- | src/xml/Makefile_insert | 1 | ||||
| -rw-r--r-- | src/xml/rebase-hrefs-test.h | 126 | ||||
| -rw-r--r-- | src/xml/rebase-hrefs.cpp | 231 | ||||
| -rw-r--r-- | src/xml/rebase-hrefs.h | 27 | ||||
| -rw-r--r-- | src/xml/repr-action-test.h | 1 | ||||
| -rw-r--r-- | src/xml/repr-io.cpp | 47 | ||||
| -rw-r--r-- | src/xml/repr.h | 3 |
7 files changed, 296 insertions, 140 deletions
diff --git a/src/xml/Makefile_insert b/src/xml/Makefile_insert index 7190b7948..b10f2448b 100644 --- a/src/xml/Makefile_insert +++ b/src/xml/Makefile_insert @@ -47,5 +47,6 @@ ink_common_sources += \ # ### CxxTest stuff #### # ###################### CXXTEST_TESTSUITES += \ + $(srcdir)/xml/rebase-hrefs-test.h \ $(srcdir)/xml/repr-action-test.h \ $(srcdir)/xml/quote-test.h diff --git a/src/xml/rebase-hrefs-test.h b/src/xml/rebase-hrefs-test.h new file mode 100644 index 000000000..e00337836 --- /dev/null +++ b/src/xml/rebase-hrefs-test.h @@ -0,0 +1,126 @@ +#include <cxxtest/TestSuite.h> + +#include <cstdlib> +#include <glib.h> + +#include "uri.h" + + +class RebaseHrefsTest : public CxxTest::TestSuite +{ + Inkscape::XML::Document *document; + Inkscape::XML::Node *a, *b, *c, *root; + +public: + + RebaseHrefsTest() + { + Inkscape::GC::init(); + + document = sp_repr_document_new("test"); + root = document->root(); + + a = document->createElement("a"); + b = document->createElement("b"); + c = document->createElement("c"); + } + virtual ~RebaseHrefsTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static RebaseHrefsTest *createSuite() { return new RebaseHrefsTest(); } + static void destroySuite( RebaseHrefsTest *suite ) { delete suite; } + + + void dump_str(gchar const *str, gchar const *prefix) + { + Glib::ustring tmp; + tmp = prefix; + tmp += " ["; + size_t const total = strlen(str); + for (unsigned i = 0; i < total; i++) { + gchar *const tmp2 = g_strdup_printf(" %02x", (0x0ff & str[i])); + tmp += tmp2; + g_free(tmp2); + } + + tmp += "]"; + g_message("%s", tmp.c_str()); + } + + void testFlipples() + { + using Inkscape::URI; + using Inkscape::MalformedURIException; + + gchar const* things[] = { + "data:foo,bar", + "http://www.google.com/image.png", + "ftp://ssd.com/doo", + "/foo/dee/bar.svg", + "foo.svg", + "file:/foo/dee/bar.svg", + "file:///foo/dee/bar.svg", + "file:foo.svg", + "/foo/bar\xe1\x84\x92.svg", + "file:///foo/bar\xe1\x84\x92.svg", + "file:///foo/bar%e1%84%92.svg", + "/foo/bar%e1%84%92.svg", + "bar\xe1\x84\x92.svg", + "bar%e1%84%92.svg", + NULL + }; + g_message("+------"); + for ( int i = 0; things[i]; i++ ) + { + try + { + URI uri(things[i]); + gboolean isAbs = g_path_is_absolute( things[i] ); + gchar *str = uri.toString(); + g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs, + (int)uri.isRelative(), + uri.getScheme(), + uri.getPath(), + uri.getOpaque(), + things[i], + str ); + g_free(str); + } + catch ( MalformedURIException err ) + { + dump_str( things[i], "MalformedURIException" ); + xmlChar *redo = xmlURIEscape((xmlChar const *)things[i]); + g_message(" gone from [%s] to [%s]", things[i], redo ); + if ( redo == NULL ) + { + URI again = URI::fromUtf8( things[i] ); + g_message(" uri from [%s] to [%s]", things[i], again.toString() ); + gboolean isAbs = g_path_is_absolute( things[i] ); + gchar *str = again.toString(); + g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs, + (int)again.isRelative(), + again.getScheme(), + again.getPath(), + again.getOpaque(), + things[i], + str ); + g_free(str); + g_message(" ----"); + } + } + } + g_message("+------"); + } +}; + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index 33b31685d..71e1cfb87 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -10,68 +10,64 @@ #include <glib/gmem.h> #include <glib/gurifuncs.h> #include <glib/gutils.h> -using Inkscape::XML::AttributeRecord; +#include <glibmm/miscutils.h> +#include <glibmm/convert.h> +#include <glibmm/uriutils.h> +using Inkscape::XML::AttributeRecord; /** - * \pre href. + * Determine if a href needs rebasing. */ -static bool -href_needs_rebasing(char const *const href) +static bool href_needs_rebasing(std::string const &href) { - g_return_val_if_fail(href, false); + bool ret = true; - if (!*href || *href == '#') { - return false; + if ( href.empty() || (href[0] == '#') ) { + ret = false; /* False (no change) is the right behaviour even when the base URI differs from the * document URI: RFC 3986 defines empty string relative URL as referring to the containing * document, rather than referring to the base URI. */ - } - - /* Don't change data or http hrefs. */ - { - char *const scheme = g_uri_parse_scheme(href); - if (scheme) { + } else { + /* Don't change data or http hrefs. */ + std::string scheme = Glib::uri_parse_scheme(href); + if ( !scheme.empty() ) { /* Assume it shouldn't be changed. This is probably wrong if the scheme is `file' * (or if the scheme of the new base is non-file, though I believe that never * happens at the time of writing), but that's rare, and we won't try too hard to * handle this now: wait until after the freeze, then add liburiparser (or similar) * as a dependency and do it properly. For now we'll just try to be simple (while * at least still correctly handling data hrefs). */ - free(scheme); - return false; + ret = false; + } else if (Glib::path_is_absolute(href)) { + /* If absolute then keep it as is. + * + * Even in the following borderline cases: + * + * - We keep it absolute even if it is in new_base (directly or indirectly). + * + * - We assume that if xlink:href is absolute then we honour it in preference to + * sodipodi:absref even if sodipodi:absref points to an existing file while xlink:href + * doesn't. This is because we aren't aware of any bugs in xlink:href handling when + * it's absolute, so we assume that it's the best value to use even in this case.) + */ + /* No strong preference on what we do for sodipodi:absref. Once we're + * confident of our handling of xlink:href and xlink:base, we should clear it. + * Though for the moment we do the simple thing: neither clear nor set it. */ + ret = false; } } - /* If absolute then keep it as is. - * - * Even in the following borderline cases: - * - * - We keep it absolute even if it is in new_base (directly or indirectly). - * - * - We assume that if xlink:href is absolute then we honour it in preference to - * sodipodi:absref even if sodipodi:absref points to an existing file while xlink:href - * doesn't. This is because we aren't aware of any bugs in xlink:href handling when - * it's absolute, so we assume that it's the best value to use even in this case.) - */ - if (g_path_is_absolute(href)) { - /* No strong preference on what we do for sodipodi:absref. Once we're - * confident of our handling of xlink:href and xlink:base, we should clear it. - * Though for the moment we do the simple thing: neither clear nor set it. */ - return false; - } - - return true; + return ret; } -static gchar * -calc_abs_href(gchar const *const abs_base_dir, gchar const *const href, - gchar const *const sp_absref) +static std::string calc_abs_href(std::string const &abs_base_dir, std::string const &href, + gchar const *const sp_absref) { - gchar *ret = g_build_filename(abs_base_dir, href, NULL); + std::string ret = Glib::build_filename(abs_base_dir, href); if ( sp_absref - && !Inkscape::IO::file_test(ret, G_FILE_TEST_EXISTS) + && !Inkscape::IO::file_test(ret.c_str(), G_FILE_TEST_EXISTS) && Inkscape::IO::file_test(sp_absref, G_FILE_TEST_EXISTS) ) { /* sodipodi:absref points to an existing file while xlink:href doesn't. @@ -93,18 +89,12 @@ calc_abs_href(gchar const *const abs_base_dir, gchar const *const href, * effic: Once we no longer consult sodipodi:absref, we can do * `if (base unchanged) { return; }' at the start of rebase_hrefs. */ - g_free(ret); - ret = g_strdup(sp_absref); + ret = sp_absref; } return ret; } -/** - * Change relative xlink:href attributes to be relative to \a new_abs_base instead of old_abs_base. - * - * Note that old_abs_base and new_abs_base must each be non-NULL, absolute directory paths. - */ Inkscape::Util::List<AttributeRecord const> Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, gchar const *const new_abs_base, @@ -115,6 +105,7 @@ Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, using Inkscape::Util::ptr_shared; using Inkscape::Util::share_string; + if (old_abs_base == new_abs_base) { return attributes; } @@ -133,7 +124,7 @@ Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, for (List<AttributeRecord const> ai(attributes); ai; ++ai) { if (ai->key == href_key) { old_href = ai->value; - if (!href_needs_rebasing(old_href)) { + if (!href_needs_rebasing(static_cast<char const *>(old_href))) { return attributes; } } else if (ai->key == absref_key) { @@ -153,23 +144,33 @@ Inkscape::XML::rebase_href_attrs(gchar const *const old_abs_base, * reversed.) */ } - gchar *const abs_href(calc_abs_href(old_abs_base, old_href, sp_absref)); - gchar const *const new_href = sp_relative_path_from_path(abs_href, new_abs_base); - ret = cons(AttributeRecord(href_key, share_string(new_href)), ret); + std::string abs_href = calc_abs_href(old_abs_base, static_cast<char const *>(old_href), sp_absref); + std::string new_href = sp_relative_path_from_path(abs_href, new_abs_base); + ret = cons(AttributeRecord(href_key, share_string(new_href.c_str())), ret); // Check if this is safe/copied or if it is only held. if (sp_absref) { /* We assume that if there wasn't previously a sodipodi:absref attribute * then we shouldn't create one. */ - ret = cons(AttributeRecord(absref_key, ( streq(abs_href, sp_absref) + ret = cons(AttributeRecord(absref_key, ( streq(abs_href.c_str(), sp_absref) ? sp_absref - : share_string(abs_href) )), + : share_string(abs_href.c_str()) )), ret); } - g_free(abs_href); + return ret; } -gchar * -Inkscape::XML::calc_abs_doc_base(gchar const *const doc_base) +// std::string Inkscape::XML::rebase_href_attrs( std::string const &oldAbsBase, std::string const &newAbsBase, gchar const * /*href*/, gchar const */*absref*/ ) +// { +// std::string ret; +// //g_message( "XX need to flip from [%s] to [%s]", oldAbsBase.c_str(), newAbsBase.c_str() ); + +// if ( oldAbsBase != newAbsBase ) { +// } + +// return ret; +// } + +std::string Inkscape::XML::calc_abs_doc_base(gchar const *doc_base) { /* Note that we don't currently try to handle the case of doc_base containing * `..' or `.' path components. This non-handling means that sometimes @@ -179,34 +180,27 @@ Inkscape::XML::calc_abs_doc_base(gchar const *const doc_base) * relative URL/IRI href processing (with liburiparser). * * (Note that one possibile difficulty with `..' is symlinks.) */ + std::string ret; if (!doc_base) { - return g_get_current_dir(); - } else if (g_path_is_absolute(doc_base)) { - return g_strdup(doc_base); + ret = Glib::get_current_dir(); + } else if (Glib::path_is_absolute(doc_base)) { + ret = doc_base; } else { - gchar *const cwd = g_get_current_dir(); - gchar *const ret = g_build_filename(cwd, doc_base, NULL); - g_free(cwd); - return ret; + ret = Glib::build_filename( Glib::get_current_dir(), doc_base ); } + + return ret; } -/** - * Change relative hrefs in doc to be relative to \a new_base instead of doc.base. - * - * (NULL doc base or new_base is interpreted as current working directory.) - * - * \param spns True iff doc should contain sodipodi:absref attributes. - */ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_base, bool const spns) { if (!doc->getBase()) { return; } - gchar *const old_abs_base = calc_abs_doc_base(doc->getBase()); - gchar *const new_abs_base = calc_abs_doc_base(new_base); + std::string old_abs_base = calc_abs_doc_base(doc->getBase()); + std::string new_abs_base = calc_abs_doc_base(new_base); /* TODO: Should handle not just image but also: * @@ -232,22 +226,26 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b for (GSList const *l = images; l != NULL; l = l->next) { Inkscape::XML::Node *ir = static_cast<SPObject *>(l->data)->getRepr(); - gchar * uri = g_strdup(ir->attribute("xlink:href")); - if (!uri) { - continue; + std::string uri; + { + gchar const *tmp = ir->attribute("xlink:href"); + if ( !tmp ) { + continue; + } + uri = tmp; } - if (!strncmp(uri, "file://", 7)) { - uri = g_strdup(g_filename_from_uri(ir->attribute("xlink:href"), NULL, NULL)); + if ( uri.substr(0, 7) == "file://" ) { + uri = Glib::filename_from_uri(uri); } // The following two cases are for absolute hrefs that can be converted to relative. // Imported images, first time rebased, need an old base. - gchar * href = uri; - if (g_path_is_absolute(href)) { - href = (gchar *) sp_relative_path_from_path(uri, old_abs_base); + std::string href = uri; + if ( Glib::path_is_absolute(href) ) { + href = sp_relative_path_from_path(uri, old_abs_base); } // Files moved from a absolute path need a new one. - if (g_path_is_absolute(href)) { - href = (gchar *) sp_relative_path_from_path(uri, new_abs_base); + if ( Glib::path_is_absolute(href) ) { + href = sp_relative_path_from_path(uri, new_abs_base); } // Other bitmaps are either really absolute, or already relative. @@ -264,52 +262,41 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b * changing non-file hrefs), which breaks if href starts with a scheme or if href contains * any escaping. */ - if (!href || !href_needs_rebasing(href)) { - g_free(uri); - continue; - } - - gchar *const abs_href(calc_abs_href(old_abs_base, href, ir->attribute("sodipodi:absref"))); - - /* todo: One difficult case once we support writing to non-file locations is where - * existing hrefs in the document point to local files. In this case, we should - * probably copy those referenced files to the new location at the same time. It's - * less clear what to do when copying from one non-file location to another. We may - * need to ask the user in some way (even if it's as a checkbox), but we'd like to - * bother the user as little as possible yet also want to warn the user about the case - * of file hrefs. */ - - gchar const *const new_href = sp_relative_path_from_path(abs_href, new_abs_base); - ir->setAttribute("sodipodi:absref", ( spns - ? abs_href - : NULL )); - if (!g_path_is_absolute(new_href)) { + if ( href_needs_rebasing(href) ) { + std::string abs_href = calc_abs_href(old_abs_base, href, ir->attribute("sodipodi:absref")); + + /* todo: One difficult case once we support writing to non-file locations is where + * existing hrefs in the document point to local files. In this case, we should + * probably copy those referenced files to the new location at the same time. It's + * less clear what to do when copying from one non-file location to another. We may + * need to ask the user in some way (even if it's as a checkbox), but we'd like to + * bother the user as little as possible yet also want to warn the user about the case + * of file hrefs. */ + + std::string new_href = sp_relative_path_from_path(abs_href, new_abs_base); + ir->setAttribute("sodipodi:absref", ( spns + ? abs_href.c_str() + : NULL )); + if (!Glib::path_is_absolute(new_href)) { #ifdef WIN32 - /* Native Windows path separators are replaced with / so that the href - * also works on Gnu/Linux and OSX */ - ir->setAttribute("xlink:href", g_strdelimit((gchar *) new_href, "\\", '/')); + /* Native Windows path separators are replaced with / so that the href + * also works on Gnu/Linux and OSX */ + ir->setAttribute("xlink:href", g_strdelimit(new_href.c_str(), "\\", '/')); #else - ir->setAttribute("xlink:href", new_href); + ir->setAttribute("xlink:href", new_href.c_str()); #endif - } else { - ir->setAttribute("xlink:href", g_filename_to_uri((gchar *) new_href, NULL, NULL)); - } + } else { + ir->setAttribute("xlink:href", g_filename_to_uri(new_href.c_str(), NULL, NULL)); + } - /* impl: I assume that if !spns then any existing sodipodi:absref is about to get - * cleared (or is already cleared) anyway, in which case it doesn't matter whether we - * clear or leave any existing sodipodi:absref value. If that assumption turns out to - * be wrong, then leaving it means risking leaving the wrong value (if xlink:href - * referred to a different file than sodipodi:absref) while clearing it means risking - * losing information. */ - - g_free(uri); - // (No need to free href, it's guaranteed to point into uri.) - g_free(abs_href); - // (No need to free new_href, it's guaranteed to point into abs_href.) + /* impl: I assume that if !spns then any existing sodipodi:absref is about to get + * cleared (or is already cleared) anyway, in which case it doesn't matter whether we + * clear or leave any existing sodipodi:absref value. If that assumption turns out to + * be wrong, then leaving it means risking leaving the wrong value (if xlink:href + * referred to a different file than sodipodi:absref) while clearing it means risking + * losing information. */ + } } - - g_free(new_abs_base); - g_free(old_abs_base); } diff --git a/src/xml/rebase-hrefs.h b/src/xml/rebase-hrefs.h index b4f288c4d..4cbdec9a5 100644 --- a/src/xml/rebase-hrefs.h +++ b/src/xml/rebase-hrefs.h @@ -9,17 +9,36 @@ struct SPDocument; namespace Inkscape { namespace XML { -gchar *calc_abs_doc_base(gchar const *doc_base); - +std::string calc_abs_doc_base(gchar const *doc_base); + +/** + * Change relative hrefs in doc to be relative to \a new_base instead of doc.base. + * + * (NULL doc base or new_base is interpreted as current working directory.) + * + * @param spns True if doc should contain sodipodi:absref attributes. + */ void rebase_hrefs(SPDocument *doc, gchar const *new_base, bool spns); +/** + * Change relative xlink:href attributes to be relative to \a new_abs_base instead of old_abs_base. + * + * Note that old_abs_base and new_abs_base must each be non-NULL, absolute directory paths. + */ Inkscape::Util::List<AttributeRecord const> rebase_href_attrs( gchar const *old_abs_base, gchar const *new_abs_base, Inkscape::Util::List<AttributeRecord const> attributes); -} -} + +// /** +// * . +// * @return a non-empty replacement href if needed, empty otherwise. +// */ +// std::string rebase_href_attrs( std::string const &oldAbsBase, std::string const &newAbsBase, gchar const *href, gchar const *absref = 0 ); + +} // namespace XML +} // namespace Inkscape #endif /* !REBASE_HREFS_H_SEEN */ diff --git a/src/xml/repr-action-test.h b/src/xml/repr-action-test.h index afc9b2c46..ae4291397 100644 --- a/src/xml/repr-action-test.h +++ b/src/xml/repr-action-test.h @@ -88,7 +88,6 @@ public: } /* lots more tests needed ... */ - }; /* diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 5f7654ba8..2a0bb6ce8 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -52,6 +52,7 @@ static void sp_repr_write_stream_root_element(Node *repr, Writer &out, int inlineattrs, int indent, gchar const *old_href_abs_base, gchar const *new_href_abs_base); + static void sp_repr_write_stream_element(Node *repr, Writer &out, gint indent_level, bool add_whitespace, Glib::QueryQuark elide_prefix, @@ -644,7 +645,7 @@ sp_repr_save_rebased_file(Document *doc, gchar const *const filename, gchar cons return false; } - gchar *old_href_abs_base = NULL; + std::string old_href_abs_base; gchar *new_href_abs_base = NULL; if (for_filename) { old_href_abs_base = calc_abs_doc_base(old_base); @@ -662,9 +663,8 @@ sp_repr_save_rebased_file(Document *doc, gchar const *const filename, gchar cons * to using sodipodi:absref instead of the xlink:href value, * then we should do `if streq() { free them and set both to NULL; }'. */ } - sp_repr_save_stream(doc, file, default_ns, compress, old_href_abs_base, new_href_abs_base); + sp_repr_save_stream(doc, file, default_ns, compress, old_href_abs_base.c_str(), new_href_abs_base); - g_free(old_href_abs_base); g_free(new_href_abs_base); if (fclose (file) != 0) { @@ -879,17 +879,16 @@ void sp_repr_write_stream( Node *repr, Writer &out, gint indent_level, } -static void -sp_repr_write_stream_element (Node * repr, Writer & out, gint indent_level, - bool add_whitespace, - Glib::QueryQuark elide_prefix, - List<AttributeRecord const> attributes, - int inlineattrs, int indent, - gchar const *const old_href_base, - gchar const *const new_href_base) +void sp_repr_write_stream_element( Node * repr, Writer & out, + gint indent_level, bool add_whitespace, + Glib::QueryQuark elide_prefix, + List<AttributeRecord const> attributes, + int inlineattrs, int indent, + gchar const *old_href_base, + gchar const *new_href_base ) { - Node *child; - bool loose; + Node *child = 0; + bool loose = false; g_return_if_fail (repr != NULL); @@ -921,6 +920,28 @@ sp_repr_write_stream_element (Node * repr, Writer & out, gint indent_level, add_whitespace = false; } + + { + GQuark const href_key = g_quark_from_static_string("xlink:href"); + GQuark const absref_key = g_quark_from_static_string("sodipodi:absref"); + + gchar const *xxHref = 0; + gchar const *xxAbsref = 0; + for ( List<AttributeRecord const> ai(attributes); ai; ++ai ) { + if ( ai->key == href_key ) { + xxHref = ai->value; + } else if ( ai->key == absref_key ) { + xxAbsref = ai->value; + } + } + + // Might add a special case for absref but no href. + if ( old_href_base && new_href_base && xxHref ) { + //g_message("href rebase test with [%s] and [%s]", xxHref, xxAbsref); + //std::string newOne = rebase_href_attrs( old_href_base, new_href_base, xxHref, xxAbsref ); + } + } + for ( List<AttributeRecord const> iter = rebase_href_attrs(old_href_base, new_href_base, attributes); iter ; ++iter ) diff --git a/src/xml/repr.h b/src/xml/repr.h index bde3e533f..5fa9387c7 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -79,10 +79,13 @@ void sp_repr_write_stream(Inkscape::XML::Node *repr, Inkscape::IO::Writer &out, gchar const *new_href_base = NULL); Inkscape::XML::Document *sp_repr_read_buf (const Glib::ustring &buf, const gchar *default_ns); Glib::ustring sp_repr_save_buf(Inkscape::XML::Document *doc); + +// TODO convert to std::string void sp_repr_save_stream(Inkscape::XML::Document *doc, FILE *to_file, gchar const *default_ns = NULL, bool compress = false, gchar const *old_href_base = NULL, gchar const *new_href_base = NULL); + bool sp_repr_save_file(Inkscape::XML::Document *doc, gchar const *filename, gchar const *default_ns=NULL); bool sp_repr_save_rebased_file(Inkscape::XML::Document *doc, gchar const *filename_utf8, gchar const *default_ns, |
