From 8394ba9d482a5a09bcfbe855c4b7b3a3bc528603 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 22 Mar 2011 19:13:39 +0100 Subject: Path. Fix for Bug #170225 (relative image paths instead of absolute). Fixed bugs: - https://launchpad.net/bugs/170225 (bzr r10124) --- src/xml/rebase-hrefs.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'src/xml') diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index b2efd7ee6..33b31685d 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -232,13 +232,40 @@ 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(l->data)->getRepr(); - gchar const *const href = ir->attribute("xlink:href"); + gchar * uri = g_strdup(ir->attribute("xlink:href")); + if (!uri) { + continue; + } + if (!strncmp(uri, "file://", 7)) { + uri = g_strdup(g_filename_from_uri(ir->attribute("xlink:href"), NULL, NULL)); + } + // 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); + } + // 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); + } + // Other bitmaps are either really absolute, or already relative. + +#ifdef WIN32 + /* Windows relative path needs their native separators before we + * compare it to native baserefs. */ + if (!g_path_is_absolute(href)) { + g_strdelimit(href, "/", '\\'); + } +#endif + /* TODO: Most of this function currently treats href as if it were a simple filename * (e.g. passing it to g_path_is_absolute, g_build_filename or IO::file_test, or avoiding * 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; } @@ -253,10 +280,21 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b * of file hrefs. */ gchar const *const new_href = sp_relative_path_from_path(abs_href, new_abs_base); - ir->setAttribute("xlink:href", new_href); ir->setAttribute("sodipodi:absref", ( spns ? abs_href : NULL )); + if (!g_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, "\\", '/')); +#else + ir->setAttribute("xlink:href", new_href); +#endif + } else { + ir->setAttribute("xlink:href", g_filename_to_uri((gchar *) new_href, 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 @@ -264,8 +302,10 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b * 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 used_abs_href.) */ + // (No need to free new_href, it's guaranteed to point into abs_href.) } g_free(new_abs_base); -- cgit v1.2.3 From a4d0a358424440128cd4c4fb2915ccc4b86f4587 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 5 May 2011 23:21:51 -0700 Subject: Adding initial cut of resource manager. (bzr r10198) --- src/xml/Makefile_insert | 1 + src/xml/rebase-hrefs-test.h | 126 ++++++++++++++++++++++++ src/xml/rebase-hrefs.cpp | 231 +++++++++++++++++++++----------------------- src/xml/rebase-hrefs.h | 27 +++++- src/xml/repr-action-test.h | 1 - src/xml/repr-io.cpp | 47 ++++++--- src/xml/repr.h | 3 + 7 files changed, 296 insertions(+), 140 deletions(-) create mode 100644 src/xml/rebase-hrefs-test.h (limited to 'src/xml') 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 + +#include +#include + +#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 #include #include -using Inkscape::XML::AttributeRecord; +#include +#include +#include +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 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 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(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(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(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 rebase_href_attrs( gchar const *old_abs_base, gchar const *new_abs_base, Inkscape::Util::List 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 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 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 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 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, -- cgit v1.2.3 From 433bde5f59b67c04fdbb82d484e823a2cfd8624c Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 6 May 2011 21:49:50 -0700 Subject: Fix windows build. (bzr r10199) --- src/xml/rebase-hrefs.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/xml') diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index 71e1cfb87..4a7e050fa 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -252,8 +252,8 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b #ifdef WIN32 /* Windows relative path needs their native separators before we * compare it to native baserefs. */ - if (!g_path_is_absolute(href)) { - g_strdelimit(href, "/", '\\'); + if ( !Glib::path_is_absolute(href) ) { + std::replace(href.begin(), href.end(), '/', '\\'); } #endif @@ -281,10 +281,9 @@ void Inkscape::XML::rebase_hrefs(SPDocument *const doc, gchar const *const new_b #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(new_href.c_str(), "\\", '/')); -#else - ir->setAttribute("xlink:href", new_href.c_str()); + std::replace(href.begin(), href.end(), '\\', '/'); #endif + ir->setAttribute("xlink:href", new_href.c_str()); } else { ir->setAttribute("xlink:href", g_filename_to_uri(new_href.c_str(), NULL, NULL)); } -- cgit v1.2.3 From 0ddedab9c6185028661dcaaac9f6fbca4c9e93fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Jun 2011 18:27:29 +0000 Subject: work in progress cmake commit: - cmake now builds all files that automake does but does NOT link yet - inlcudes nasty hard coded paths and libs (will replace once linking works) (bzr r10272) --- src/xml/CMakeLists.txt | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 775a4e72f..b92d82489 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -1,21 +1,21 @@ -SET(xml_SRC -composite-node-observer.cpp -croco-node-iface.cpp -event.cpp -log-builder.cpp -node-fns.cpp -quote.cpp -#quote-test.cpp -repr.cpp -#repr-action-test.cpp -repr-css.cpp -repr-io.cpp -repr-sorting.cpp -repr-util.cpp -simple-document.cpp -simple-node.cpp -subtree.cpp +set(xml_SRC + composite-node-observer.cpp + croco-node-iface.cpp + event.cpp + log-builder.cpp + node-fns.cpp + quote.cpp + repr.cpp + repr-css.cpp + repr-io.cpp + repr-sorting.cpp + repr-util.cpp + simple-document.cpp + simple-node.cpp + subtree.cpp + helper-observer.cpp + rebase-hrefs.cpp ) -ADD_LIBRARY(xml STATIC ${xml_SRC}) -TARGET_LINK_LIBRARIES(xml -2geom ${INKSCAPE_LIBS}) \ No newline at end of file + +add_library(xml STATIC ${xml_SRC}) +target_link_libraries(xml 2geom ${INKSCAPE_LIBS}) \ No newline at end of file -- cgit v1.2.3 From de03354959190a2c5392d79e03dd22dc45777e41 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Jun 2011 21:27:00 +0000 Subject: cmake: give all libs a _LIB suffix, workaround 'debug' being confused with cake keyword, and also dont mix up dor names with libs. (bzr r10274) --- src/xml/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index b92d82489..1aafe2d21 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -17,5 +17,5 @@ set(xml_SRC rebase-hrefs.cpp ) -add_library(xml STATIC ${xml_SRC}) -target_link_libraries(xml 2geom ${INKSCAPE_LIBS}) \ No newline at end of file +add_library(xml_LIB STATIC ${xml_SRC}) +target_link_libraries(xml_LIB 2geom_LIB ${INKSCAPE_LIBS}) -- cgit v1.2.3 From 7172735786c43c2305a92ffd4e5d285d11f88f7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 13 Jun 2011 00:19:17 +0000 Subject: cmake: turns out my recent commits (which I undid) were not incorrect, variables were set in subdirectories then used in the parent directory, where they were still unset. Fixing this broke the build because some files in the subdir were not compiling. (bzr r10276) --- src/xml/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 1aafe2d21..353c96998 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -1,3 +1,4 @@ + set(xml_SRC composite-node-observer.cpp croco-node-iface.cpp @@ -17,5 +18,4 @@ set(xml_SRC rebase-hrefs.cpp ) -add_library(xml_LIB STATIC ${xml_SRC}) -target_link_libraries(xml_LIB 2geom_LIB ${INKSCAPE_LIBS}) +add_library(xml_LIB ${xml_SRC}) -- cgit v1.2.3 From 2c5f1ac093f8d674dae8fc1cae88862d02468356 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 13 Jun 2011 02:33:03 +0000 Subject: cmake: now builds without having most of the source listed in 1 file. (bzr r10278) --- src/xml/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 353c96998..3cca53fd8 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -18,4 +18,5 @@ set(xml_SRC rebase-hrefs.cpp ) -add_library(xml_LIB ${xml_SRC}) +# add_library(xml_LIB ${xml_SRC}) +add_inkscape_source("${xml_SRC}") -- cgit v1.2.3 From b7a4f23ed217a36eaaefe8f707bcc1b968d1e562 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 13 Jun 2011 05:39:42 +0000 Subject: cmake: - group source/headers per library (for some IDE's) - include headers with source listing (also for IDE's) - remove unneeded Find modules (bzr r10281) --- src/xml/CMakeLists.txt | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 3cca53fd8..d7a0e197d 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -16,7 +16,38 @@ set(xml_SRC subtree.cpp helper-observer.cpp rebase-hrefs.cpp + + attribute-record.h + comment-node.h + composite-node-observer.h + croco-node-iface.h + document.h + element-node.h + event-fns.h + event.h + helper-observer.h + invalid-operation-exception.h + log-builder.h + node-event-vector.h + node-fns.h + node-iterators.h + node-observer.h + node.h + pi-node.h + quote-test.h + quote.h + rebase-hrefs-test.h + rebase-hrefs.h + repr-action-test.h + repr-sorting.h + repr.h + simple-document.h + simple-node.h + sp-css-attr.h + subtree.h + text-node.h + xml-forward.h ) -# add_library(xml_LIB ${xml_SRC}) +# add_inkscape_lib(xml_LIB "${xml_SRC}") add_inkscape_source("${xml_SRC}") -- cgit v1.2.3 From 2045221082a4aed0dcbbd71d36393a2498396a10 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 2 Jul 2011 09:58:37 +0000 Subject: added missing header (bzr r10397) --- src/xml/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index d7a0e197d..4f86599de 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -17,6 +17,9 @@ set(xml_SRC helper-observer.cpp rebase-hrefs.cpp + + # ------- + # Headers attribute-record.h comment-node.h composite-node-observer.h -- cgit v1.2.3 From e24a1e86c4d4cdf272e3ec0cd33b31bf2d59244c Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Wed, 20 Jul 2011 01:01:23 +0200 Subject: Remove deprecated Glib symbols Fixed bugs: - https://launchpad.net/bugs/367606 (bzr r10480) --- src/xml/repr-util.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 9405cde01..db1d5591e 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -494,9 +494,9 @@ sp_repr_get_boolean(Inkscape::XML::Node *repr, gchar const *key, unsigned int *v v = repr->attribute(key); if (v != NULL) { - if (!g_strcasecmp(v, "true") || - !g_strcasecmp(v, "yes" ) || - !g_strcasecmp(v, "y" ) || + if (!g_ascii_strcasecmp(v, "true") || + !g_ascii_strcasecmp(v, "yes" ) || + !g_ascii_strcasecmp(v, "y" ) || (atoi(v) != 0)) { *val = TRUE; } else { -- cgit v1.2.3 From 35301e418f34ce11cfed9c11a7f8a923faf48cf0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Aug 2011 20:30:39 +0200 Subject: Added comments. (bzr r10596) --- src/xml/repr-css.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 5 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index dc6494bcd..5c8c6bf4b 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -1,6 +1,21 @@ /* * bulia byak -*/ + * Tavmjong Bah (Documentation) + * + * Functions to manipulate SPCSSAttr which is a class derived from Inkscape::XML::Node See + * sp-css-attr.h and node.h + * + * SPCSSAttr is a special node type where the "attributes" are the properties in an element's style + * attribute. For example, style="fill:blue;stroke:none" is stored in a List (Inkscape::Util:List) + * where the key is the property (e.g. "fill" or "stroke") and the value is the property's value + * (e.g. "blue" or "none"). An element's properties are manipulated by adding, removing, or + * changing an item in the List. Utility functions are provided to go back and forth between the + * two ways of representing properties (by a string or by a list). + * + * Use sp_repr_write_string to go from a property list to a style string. + * + * Use sp_repr_css_add_component to parse a property string and add the properties to the List. + */ #define SP_REPR_CSS_C @@ -35,7 +50,9 @@ protected: static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr); - +/** + * Creates an empty SPCSSAttr (a class for manipulating CSS style properties). + */ SPCSSAttr * sp_repr_css_attr_new() { @@ -46,6 +63,9 @@ sp_repr_css_attr_new() return new SPCSSAttrImpl(attr_doc); } +/** + * Unreferences an SPCSSAttr (will be garbage collected if no references remain). + */ void sp_repr_css_attr_unref(SPCSSAttr *css) { @@ -53,6 +73,12 @@ sp_repr_css_attr_unref(SPCSSAttr *css) Inkscape::GC::release((Node *) css); } +/** + * Creates a new SPCSSAttr with one attribute (i.e. style) copied from an existing repr (node). The + * repr attribute data is in the form of a char const * string (e.g. fill:#00ff00;stroke:none). The + * string is parsed by libcroco which returns a CRDeclaration list (a typical C linked list) of + * properties and values. This list is then used to fill the attributes of the new SPCSSAttr. + */ SPCSSAttr *sp_repr_css_attr(Node *repr, gchar const *attr) { g_assert(repr != NULL); @@ -63,6 +89,9 @@ SPCSSAttr *sp_repr_css_attr(Node *repr, gchar const *attr) return css; } +/** + * Adds an attribute to an existing SPCSAttr with the cascaded value including all parents. + */ static void sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node *repr, gchar const *attr) { @@ -72,11 +101,12 @@ sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node *repr, gchar const *at if (parent) { sp_repr_css_attr_inherited_recursive(css, parent, attr); } - sp_repr_css_add_components(css, repr, attr); } - +/** + * Creates a new SPCSSAttr with one attribute whose value is determined by cascading. + */ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) { g_assert(repr != NULL); @@ -89,6 +119,9 @@ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) return css; } +/** + * Adds components (style properties) to an existing SPCSAttr from a character string. + */ static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) { @@ -100,6 +133,10 @@ sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) sp_repr_css_attr_add_from_string(css, data); } +/** + * Returns a character string of the value of a given style property or a default value if the + * attribute is not found. + */ char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval) { @@ -112,6 +149,9 @@ sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval) : attr ); } +/** + * Returns true if a style property is present and its value is unset. + */ bool sp_repr_css_property_is_unset(SPCSSAttr *css, gchar const *name) { @@ -123,6 +163,9 @@ sp_repr_css_property_is_unset(SPCSSAttr *css, gchar const *name) } +/** + * Set a style property to a new value (e.g. fill to #ffff00). + */ void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value) { @@ -132,6 +175,9 @@ sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value) ((Node *) css)->setAttribute(name, value, false); } +/** + * Set a style property to "inkscape:unset". + */ void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name) { @@ -141,6 +187,9 @@ sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name) ((Node *) css)->setAttribute(name, "inkscape:unset", false); } +/** + * Return the value of a style property if property define, or a default value if not. + */ double sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval) { @@ -150,6 +199,9 @@ sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval) return sp_repr_get_double_attribute((Node *) css, name, defval); } +/** + * Write a style attribute string from a list of properties stored in an SPCSAttr object. + */ gchar * sp_repr_css_write_string(SPCSSAttr *css) { @@ -186,6 +238,9 @@ sp_repr_css_write_string(SPCSSAttr *css) return (buffer.empty() ? NULL : g_strdup (buffer.c_str())); } +/** + * Sets an attribute (e.g. style) to a string created from a list of style properties. + */ void sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) { @@ -200,6 +255,9 @@ sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) if (value) g_free (value); } +/** + * Loops through a List of style properties, printing key/value pairs. + */ void sp_repr_css_print(SPCSSAttr *css) { @@ -212,6 +270,9 @@ sp_repr_css_print(SPCSSAttr *css) } } +/** + * Merges two SPCSSAttr's. Properties in src overwrite properties in dst if present in both. + */ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) { @@ -219,9 +280,12 @@ sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) g_assert(src != NULL); dst->mergeFrom(src, ""); + sp_repr_css_print( dst ); } - +/** + * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + */ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { @@ -234,6 +298,8 @@ sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) } /** + * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + * * \pre decl_list != NULL */ static void @@ -248,6 +314,10 @@ sp_repr_css_merge_from_decl_list(SPCSSAttr *css, CRDeclaration const *const decl } } +/** + * Use libcroco to parse a string for CSS properties and then merge + * them into an existing SPCSSAttr. + */ void sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p) { @@ -261,6 +331,10 @@ sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p) } } +/** + * Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given + * SPCSAttr, and then replaces the that SPCSAttr with the new one. + */ void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr) { -- cgit v1.2.3 From f5e85edb29a2e69721ddd2121b649a2402bed994 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Aug 2011 20:33:41 +0200 Subject: Remove forgotten call to print routine. (bzr r10597) --- src/xml/repr-css.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 5c8c6bf4b..46a16715c 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -280,7 +280,6 @@ sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) g_assert(src != NULL); dst->mergeFrom(src, ""); - sp_repr_css_print( dst ); } /** -- cgit v1.2.3 From 8a73582fd88bffa4e219dfce758a930b43c06a98 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 8 Sep 2011 16:27:40 +0200 Subject: Preserve CDATA sections on output. (bzr r10625) --- src/xml/document.h | 1 + src/xml/repr-io.cpp | 12 ++++++++++-- src/xml/simple-document.cpp | 4 ++++ src/xml/simple-document.h | 4 +++- src/xml/text-node.h | 13 ++++++++++++- 5 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/xml') diff --git a/src/xml/document.h b/src/xml/document.h index 98cc0522e..3bf0a63a6 100644 --- a/src/xml/document.h +++ b/src/xml/document.h @@ -92,6 +92,7 @@ public: */ virtual Node *createElement(char const *name)=0; virtual Node *createTextNode(char const *content)=0; + virtual Node *createTextNode(char const *content, bool is_CData)=0; virtual Node *createComment(char const *content)=0; virtual Node *createPI(char const *target, char const *content)=0; /*@}*/ diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 2a0bb6ce8..365415488 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -24,6 +24,7 @@ #include "xml/attribute-record.h" #include "xml/rebase-hrefs.h" #include "xml/simple-document.h" +#include "xml/text-node.h" #include "io/sys.h" #include "io/uristream.h" @@ -497,7 +498,9 @@ sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ return NULL; // we do not preserve all-whitespace nodes unless we are asked to } - return xml_doc->createTextNode(reinterpret_cast(node->content)); + // We keep track of original node type so that CDATA sections are preserved on output. + return xml_doc->createTextNode(reinterpret_cast(node->content), + node->type == XML_CDATA_SECTION_NODE ); } if (node->type == XML_COMMENT_NODE) { @@ -849,7 +852,12 @@ void sp_repr_write_stream( Node *repr, Writer &out, gint indent_level, { switch (repr->type()) { case Inkscape::XML::TEXT_NODE: { - repr_quote_write( out, repr->content() ); + if( dynamic_cast(repr)->is_CData() ) { + // Preserve CDATA sections, not converting '&' to &, etc. + out.printf( "", repr->content() ); + } else { + repr_quote_write( out, repr->content() ); + } break; } case Inkscape::XML::COMMENT_NODE: { diff --git a/src/xml/simple-document.cpp b/src/xml/simple-document.cpp index 2807133af..0287c4458 100644 --- a/src/xml/simple-document.cpp +++ b/src/xml/simple-document.cpp @@ -58,6 +58,10 @@ Node *SimpleDocument::createTextNode(char const *content) { return new TextNode(Util::share_string(content), this); } +Node *SimpleDocument::createTextNode(char const *content, bool const is_CData) { + return new TextNode(Util::share_string(content), this, is_CData); +} + Node *SimpleDocument::createComment(char const *content) { return new CommentNode(Util::share_string(content), this); } diff --git a/src/xml/simple-document.h b/src/xml/simple-document.h index 8a37c577c..ff1d94b0c 100644 --- a/src/xml/simple-document.h +++ b/src/xml/simple-document.h @@ -31,7 +31,7 @@ class SimpleDocument : public SimpleNode, public: explicit SimpleDocument() : SimpleNode(g_quark_from_static_string("xml"), this), - _in_transaction(false) {} + _in_transaction(false), _is_CData(false) {} NodeType type() const { return Inkscape::XML::DOCUMENT_NODE; } @@ -44,6 +44,7 @@ public: Node *createElement(char const *name); Node *createTextNode(char const *content); + Node *createTextNode(char const *content, bool const is_CData); Node *createComment(char const *content); Node *createPI(char const *target, char const *content); @@ -76,6 +77,7 @@ protected: private: bool _in_transaction; LogBuilder _log_builder; + bool _is_CData; }; } diff --git a/src/xml/text-node.h b/src/xml/text-node.h index b0b7c884b..2fabd6953 100644 --- a/src/xml/text-node.h +++ b/src/xml/text-node.h @@ -30,14 +30,25 @@ struct TextNode : public SimpleNode { : SimpleNode(g_quark_from_static_string("string"), doc) { setContent(content); + _is_CData = false; + } + TextNode(Util::ptr_shared content, Document *doc, bool is_CData) + : SimpleNode(g_quark_from_static_string("string"), doc) + { + setContent(content); + _is_CData = is_CData; } TextNode(TextNode const &other, Document *doc) - : SimpleNode(other, doc) {} + : SimpleNode(other, doc) { + _is_CData = other._is_CData; + } Inkscape::XML::NodeType type() const { return Inkscape::XML::TEXT_NODE; } + bool is_CData() const { return _is_CData; } protected: SimpleNode *_duplicate(Document* doc) const { return new TextNode(*this, doc); } + bool _is_CData; }; } -- cgit v1.2.3 From 56c911746539f515dcf162c5d134abf76557a287 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Sep 2011 21:08:22 +0200 Subject: Use CSSOStringStream in writing number strings parsed by libcroco as libcroco uses %.17f for formatting, resulting in trailing zeros or small rounding errors. (bzr r10629) --- src/xml/repr-css.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 46a16715c..cb30e65ce 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -14,13 +14,15 @@ * * Use sp_repr_write_string to go from a property list to a style string. * - * Use sp_repr_css_add_component to parse a property string and add the properties to the List. */ #define SP_REPR_CSS_C #include +#include +#include #include +#include "svg/css-ostringstream.h" #include "xml/repr.h" #include "xml/simple-document.h" @@ -120,7 +122,9 @@ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) } /** - * Adds components (style properties) to an existing SPCSAttr from a character string. + * Adds components (style properties) to an existing SPCSAttr from the specified attribute's data + * (nominally a style attribute). + * */ static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) @@ -228,6 +232,7 @@ sp_repr_css_write_string(SPCSSAttr *css) } } else { buffer.append(iter->value); // unquoted + g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value ); } if (rest(iter)) { @@ -250,6 +255,12 @@ sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) gchar *value = sp_repr_css_write_string(css); + /* + * If the new value is different from the old value, this will sometimes send a signal via + * CompositeNodeObserver::notiftyAttributeChanged() which results in calling + * SPObject::sp_object_repr_attr_changed and thus updates the object's SPStyle. This update + * results in another call to repr->setAttribute(). + */ repr->setAttribute(attr, value); if (value) g_free (value); @@ -291,7 +302,22 @@ sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) guchar *const str_value_unsigned = cr_term_to_string(decl->value); gchar *const str_value = reinterpret_cast(str_value_unsigned); gchar *value_unquoted = attribute_unquote (str_value); // libcroco returns strings quoted in "" - ((Node *) css)->setAttribute(decl->property->stryng->str, value_unquoted, false); + + // libcroco uses %.17f for formatting... leading to trailing zeros or small rounding errors. + // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has + // the additional benefit of respecting the numerical precission set in the SVG Output + // preferences. We assume any numerical part comes first (if not, the whole string is copied). + std::stringstream ss( value_unquoted ); + double number; + std::string characters; + bool number_valid = !(ss >> number).fail(); + if( !number_valid ) ss.clear(); + bool character_valid = !(ss >> characters).fail(); + Inkscape::CSSOStringStream os; + if( number_valid ) os << number; + if( character_valid ) os << characters; + + ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); g_free(value_unquoted); g_free(str_value); } @@ -332,7 +358,8 @@ sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p) /** * Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given - * SPCSAttr, and then replaces the that SPCSAttr with the new one. + * SPCSAttr, and then replaces that SPCSAttr with the new one. This is called, for example, for + * each object in turn when a selection's style is updated via sp_desktop_set_style(). */ void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr) -- cgit v1.2.3 From f21461e44a12ad13d86c125b095a8793e24dffda Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 16 Sep 2011 01:47:40 +0200 Subject: Fix incorrect argument in call to varargs function in xml/repr-css.cpp (bzr r10630) --- src/xml/repr-css.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index cb30e65ce..8e8042dfd 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -232,7 +232,7 @@ sp_repr_css_write_string(SPCSSAttr *css) } } else { buffer.append(iter->value); // unquoted - g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value ); + g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value.pointer() ); } if (rest(iter)) { -- cgit v1.2.3 From 043e682872b382312e0dc58c197ce452b1cf6766 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 16 Sep 2011 09:12:03 +0200 Subject: Remove left over debug g_warning... and the cause of compilation problems. (bzr r10631) --- src/xml/repr-css.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 8e8042dfd..7db1e8b86 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -232,7 +232,6 @@ sp_repr_css_write_string(SPCSSAttr *css) } } else { buffer.append(iter->value); // unquoted - g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value.pointer() ); } if (rest(iter)) { @@ -316,7 +315,7 @@ sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) Inkscape::CSSOStringStream os; if( number_valid ) os << number; if( character_valid ) os << characters; - + ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); g_free(value_unquoted); g_free(str_value); -- cgit v1.2.3 From 278bc7c50017df7bf9ae28e639c3aecc072fa3df Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 28 Sep 2011 15:18:38 +0200 Subject: Fixed problem with font names that contain spaces. (bzr r10649) --- src/xml/repr-css.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 7db1e8b86..a0b45a42e 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -232,6 +232,7 @@ sp_repr_css_write_string(SPCSSAttr *css) } } else { buffer.append(iter->value); // unquoted + g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value.pointer() ); } if (rest(iter)) { @@ -309,13 +310,17 @@ sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) std::stringstream ss( value_unquoted ); double number; std::string characters; + std::string temp; bool number_valid = !(ss >> number).fail(); if( !number_valid ) ss.clear(); - bool character_valid = !(ss >> characters).fail(); + while( !(ss >> temp).eof() ) { + characters += temp; + characters += " "; + } + characters += temp; Inkscape::CSSOStringStream os; if( number_valid ) os << number; - if( character_valid ) os << characters; - + os << characters; ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); g_free(value_unquoted); g_free(str_value); -- cgit v1.2.3 From a87e24fa2d1c86e85444e177a3c3156f4d630c3f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 2 Oct 2011 15:40:19 +0200 Subject: Removed forgotten debug statement. (bzr r10657) --- src/xml/repr-css.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index a0b45a42e..8de85c36d 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -232,7 +232,6 @@ sp_repr_css_write_string(SPCSSAttr *css) } } else { buffer.append(iter->value); // unquoted - g_warning("sp_repr_css_write_string: %s %s", g_quark_to_string(iter->key), iter->value.pointer() ); } if (rest(iter)) { -- cgit v1.2.3 From 6343a24c5cd0a998e00ae05fc6abe2081be21c71 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 3 Oct 2011 00:24:15 -0700 Subject: Doxygen cleanup. (bzr r10660) --- src/xml/croco-node-iface.cpp | 3 +-- src/xml/log-builder.cpp | 5 +++-- src/xml/repr-util.cpp | 12 ++++++------ src/xml/simple-document.cpp | 5 +++-- src/xml/simple-node.cpp | 5 +++-- 5 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/xml') diff --git a/src/xml/croco-node-iface.cpp b/src/xml/croco-node-iface.cpp index afea4abba..72bcba7f3 100644 --- a/src/xml/croco-node-iface.cpp +++ b/src/xml/croco-node-iface.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -46,7 +45,7 @@ static gboolean is_element_node(CRXMLNodePtr n) { return static_cast * diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index db1d5591e..aa244d842 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -1,4 +1,5 @@ -/** \file +/** + * @file * Miscellaneous helpers for reprs. */ @@ -404,7 +405,7 @@ int sp_repr_compare_position(Inkscape::XML::Node const *first, Inkscape::XML::No } /** - * @brief Find an element node using an unique attribute + * Find an element node using an unique attribute. * * This function returns the first child of the specified node that has the attribute * @c key equal to @c value. Note that this function does not recurse. @@ -414,10 +415,9 @@ int sp_repr_compare_position(Inkscape::XML::Node const *first, Inkscape::XML::No * @param value The value of the attribute to look for * @relatesalso Inkscape::XML::Node */ -Inkscape::XML::Node * -sp_repr_lookup_child(Inkscape::XML::Node *repr, - gchar const *key, - gchar const *value) +Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr, + gchar const *key, + gchar const *value) { g_return_val_if_fail(repr != NULL, NULL); for ( Inkscape::XML::Node *child = repr->firstChild() ; child ; child = child->next() ) { diff --git a/src/xml/simple-document.cpp b/src/xml/simple-document.cpp index 0287c4458..bae28e4b4 100644 --- a/src/xml/simple-document.cpp +++ b/src/xml/simple-document.cpp @@ -1,5 +1,6 @@ -/** @file - * @brief Garbage collected XML document implementation +/** + * @file + * Garbage collected XML document implementation. */ /* Copyright 2004-2005 MenTaLguY * diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index b7c0c34ed..792706a18 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -1,5 +1,6 @@ -/** @file - * @brief Garbage collected XML node implementation +/** + * @file + * Garbage collected XML node implementation. */ /* Copyright 2003-2005 MenTaLguY * Copyright 2003 Nathan Hurst -- cgit v1.2.3 From 23ea206a1348414f67fee482f63a69b1d90b0df6 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 3 Oct 2011 22:43:09 -0700 Subject: Purging some forward.h files. (bzr r10664) --- src/xml/document.h | 1 - src/xml/event.h | 1 - src/xml/log-builder.h | 4 +++- src/xml/node-observer.h | 3 ++- src/xml/node.h | 7 +++++- src/xml/repr-sorting.h | 9 +++++++- src/xml/subtree.h | 1 - src/xml/xml-forward.h | 58 ------------------------------------------------- 8 files changed, 19 insertions(+), 65 deletions(-) delete mode 100644 src/xml/xml-forward.h (limited to 'src/xml') diff --git a/src/xml/document.h b/src/xml/document.h index 3bf0a63a6..efbc9bff7 100644 --- a/src/xml/document.h +++ b/src/xml/document.h @@ -15,7 +15,6 @@ #ifndef SEEN_INKSCAPE_XML_SP_REPR_DOC_H #define SEEN_INKSCAPE_XML_SP_REPR_DOC_H -#include "xml/xml-forward.h" #include "xml/node.h" namespace Inkscape { diff --git a/src/xml/event.h b/src/xml/event.h index 18dc47865..c2865b8c4 100644 --- a/src/xml/event.h +++ b/src/xml/event.h @@ -26,7 +26,6 @@ #include "util/share.h" #include "util/forward-pointer-iterator.h" #include "gc-managed.h" -#include "xml/xml-forward.h" #include "xml/node.h" namespace Inkscape { diff --git a/src/xml/log-builder.h b/src/xml/log-builder.h index 264c2ced7..aa8f2c1c6 100644 --- a/src/xml/log-builder.h +++ b/src/xml/log-builder.h @@ -15,12 +15,14 @@ #define SEEN_INKSCAPE_XML_LOG_BUILDER_H #include "gc-managed.h" -#include "xml/xml-forward.h" #include "xml/node-observer.h" namespace Inkscape { namespace XML { +class Event; +class Node; + /** * @brief Event log builder * diff --git a/src/xml/node-observer.h b/src/xml/node-observer.h index c3ec437b5..59142be8c 100644 --- a/src/xml/node-observer.h +++ b/src/xml/node-observer.h @@ -20,7 +20,6 @@ #include #include "util/share.h" -#include "xml/xml-forward.h" #ifndef INK_UNUSED #define INK_UNUSED(x) ((void)(x)) @@ -29,6 +28,8 @@ namespace Inkscape { namespace XML { +class Node; + /** * @brief Interface for XML node observers * diff --git a/src/xml/node.h b/src/xml/node.h index 17479e50b..8b7dea203 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -21,11 +21,16 @@ #include #include "gc-anchored.h" #include "util/list.h" -#include "xml/xml-forward.h" namespace Inkscape { namespace XML { +struct AttributeRecord; +struct Document; +class Event; +class NodeObserver; +struct NodeEventVector; + /** * @brief Enumeration containing all supported node types. */ diff --git a/src/xml/repr-sorting.h b/src/xml/repr-sorting.h index d560dfa26..dddb8588c 100644 --- a/src/xml/repr-sorting.h +++ b/src/xml/repr-sorting.h @@ -7,7 +7,14 @@ #ifndef SEEN_XML_REPR_SORTING_H #define SEEN_XML_REPR_SORTING_H -#include "xml/xml-forward.h" +namespace Inkscape { +namespace XML { + +class Node; + +} // namespace XML +} // namespace Inkscape + Inkscape::XML::Node *LCA(Inkscape::XML::Node *a, Inkscape::XML::Node *b); Inkscape::XML::Node const *LCA(Inkscape::XML::Node const *a, Inkscape::XML::Node const *b); diff --git a/src/xml/subtree.h b/src/xml/subtree.h index deee0cab1..11bf515f1 100644 --- a/src/xml/subtree.h +++ b/src/xml/subtree.h @@ -16,7 +16,6 @@ #define SEEN_INKSCAPE_XML_SUBTREE_H #include "gc-managed.h" -#include "xml/xml-forward.h" #include "xml/composite-node-observer.h" namespace Inkscape { diff --git a/src/xml/xml-forward.h b/src/xml/xml-forward.h deleted file mode 100644 index bc7b8a405..000000000 --- a/src/xml/xml-forward.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __SEEN_XML_FORWARD_H__ -#define __SEEN_XML_FORWARD_H__ - -/** @file - * @brief Forward declarations for the XML namespace. - */ -/* Authors: - * Krzysztof KosiƄski - * - * Copyright (C) 2008 Authors - * - * Released under GNU GPL. Read the file 'COPYING' for more information. - */ - -namespace Inkscape { -namespace XML { - -/* Copied from the relevant Doxygen page */ - -struct AttributeRecord; -struct CommentNode; -class CompositeNodeObserver; -struct Document; -class ElementNode; -class Event; -class EventAdd; -class EventDel; -class EventChgAttr; -class EventChgContent; -class EventChgOrder; -class InvalidOperationException; -class LogBuilder; -struct NodeEventVector; -struct NodeSiblingIteratorStrategy; -struct NodeParentIteratorStrategy; -class NodeObserver; -class Node; -struct PINode; -class SimpleDocument; -class SimpleNode; -class Subtree; -struct TextNode; - -} // namespace XML -} // namespace Inkscape - -#endif // __SEEN_XML_FORWARD_H__ - -/* - 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 : -- cgit v1.2.3 From 4b81b6cce7f299433add1815470732a013710342 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 8 Oct 2011 17:34:23 +1100 Subject: update cmake file lists (bzr r10673) --- src/xml/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/CMakeLists.txt b/src/xml/CMakeLists.txt index 4f86599de..2a9789384 100644 --- a/src/xml/CMakeLists.txt +++ b/src/xml/CMakeLists.txt @@ -49,7 +49,6 @@ set(xml_SRC sp-css-attr.h subtree.h text-node.h - xml-forward.h ) # add_inkscape_lib(xml_LIB "${xml_SRC}") -- cgit v1.2.3 From 57558641a9819e4da97bc014ac35f9323306ae1f Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Thu, 10 Nov 2011 23:23:06 +0100 Subject: cppcheck: initialization / warning cleanup (bzr r10736) --- src/xml/repr-css.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/xml') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 8de85c36d..ced4f5da4 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -307,7 +307,7 @@ sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) // the additional benefit of respecting the numerical precission set in the SVG Output // preferences. We assume any numerical part comes first (if not, the whole string is copied). std::stringstream ss( value_unquoted ); - double number; + double number = 0; std::string characters; std::string temp; bool number_valid = !(ss >> number).fail(); -- cgit v1.2.3 From 771029025214cffd0bc9783656c29e08ad208743 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 29 Nov 2011 12:27:10 +0100 Subject: Add possibility to check validity of attributes and usefulness of properties. This code adds the ability to check for every elment in an SVG document if its attributes are valid and the styling properties are useful. Options under the SVG Output section of the Inkscape Preferences dialog control what should be checked when, and what actions should be taken if invalid attributes or non-useful properties are found. (bzr r10753) --- src/xml/repr-io.cpp | 23 ++++++++++++++++++- src/xml/simple-node.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 7 deletions(-) (limited to 'src/xml') diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 365415488..39eb2637a 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -33,6 +33,8 @@ #include "extension/extension.h" +#include "attribute-rel-util.h" + #include "preferences.h" using Inkscape::IO::Writer; @@ -256,6 +258,7 @@ int XmlSource::close() Document * sp_repr_read_file (const gchar * filename, const gchar *default_ns) { + // g_warning( "Reading file: %s", filename ); xmlDocPtr doc = 0; Document * rdoc = 0; @@ -446,6 +449,18 @@ sp_repr_do_read (xmlDocPtr doc, const gchar *default_ns) promote_to_namespace(root, INKSCAPE_EXTENSION_NS_NC); } } + + + // Clean unnecessary attributes and style properties from SVG documents. (Controlled by + // preferences.) Note: internal Inkscape svg files will also be cleaned (filters.svg, + // icons.svg). How can one tell if a file is internal? + if ( !strcmp(root->name(), "svg:svg" ) ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool clean = prefs->getBool("/options/svgoutput/check_on_reading"); + if( clean ) { + sp_attribute_clean_tree( root ); + } + } } g_hash_table_destroy (prefix_map); @@ -806,6 +821,12 @@ sp_repr_write_stream_root_element(Node *repr, Writer &out, using Inkscape::Util::ptr_shared; g_assert(repr != NULL); + + // Clean unnecessary attributes and stype properties. (Controlled by preferences.) + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool clean = prefs->getBool("/options/svgoutput/check_on_writing"); + if (clean) sp_attribute_clean_tree( repr ); + Glib::QueryQuark xml_prefix=g_quark_from_static_string("xml"); NSMap ns_map; @@ -928,7 +949,7 @@ void sp_repr_write_stream_element( Node * repr, Writer & out, add_whitespace = false; } - + // THIS DOESN'T APPEAR TO DO ANYTHING. Can it be commented out or deleted? { GQuark const href_key = g_quark_from_static_string("xlink:href"); GQuark const absref_key = g_quark_from_static_string("sodipodi:absref"); diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 792706a18..44ddba237 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -1,6 +1,5 @@ -/** - * @file - * Garbage collected XML node implementation. +/** @file + * @brief Garbage collected XML node implementation */ /* Copyright 2003-2005 MenTaLguY * Copyright 2003 Nathan Hurst @@ -17,8 +16,11 @@ #include #include + #include +#include "preferences.h" + #include "xml/node.h" #include "xml/simple-node.h" #include "xml/node-event-vector.h" @@ -29,6 +31,8 @@ #include "util/share.h" #include "util/format.h" +#include "attribute-rel-util.h" + namespace Inkscape { namespace XML { @@ -312,6 +316,47 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ { g_return_if_fail(name && *name); + // Check usefulness of attributes on elements in the svg namespace, optionally don't add them to tree. + Glib::ustring element = g_quark_to_string(_name); + //g_warning("setAttribute: %s: %s: %s", element.c_str(), name, value); + + gchar* cleaned_value = g_strdup( value ); + + // Only check elements in SVG name space and don't block setting attribute to NULL. + if( element.substr(0,4) == "svg:" && value != NULL) { + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if( prefs->getBool("/options/svgoutput/check_on_editing") ) { + + gchar const *id_char = attribute("id"); + Glib::ustring id = (id_char == NULL ? "" : id_char ); + unsigned int flags = sp_attribute_clean_get_prefs(); + bool attr_warn = flags & SP_ATTR_CLEAN_ATTR_WARN; + bool attr_remove = flags & SP_ATTR_CLEAN_ATTR_REMOVE; + + // Check attributes + if( (attr_warn || attr_remove) && value != NULL ) { + bool is_useful = sp_attribute_check_attribute( element, id, name, attr_warn ); + if( !is_useful && attr_remove ) { + g_free( cleaned_value ); + return; // Don't add to tree. + } + } + + // Check style properties -- Note: if element is not yet inserted into + // tree (and thus has no parent), default values will not be tested. + if( !strcmp( name, "style" ) && (flags >= SP_ATTR_CLEAN_STYLE_WARN) ) { + g_free( cleaned_value ); + cleaned_value = sp_attribute_clean_style( this, value, flags ); + // if( g_strcmp0( value, cleaned_value ) ) { + // g_warning( "SimpleNode::setAttribute: %s", id.c_str() ); + // g_warning( " original: %s", value); + // g_warning( " cleaned: %s", cleaned_value); + // } + } + } + } + GQuark const key = g_quark_from_string(name); MutableList ref; @@ -322,14 +367,13 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ } ref = existing; } - Debug::EventTracker<> tracker; ptr_shared old_value=( existing ? existing->value : ptr_shared() ); ptr_shared new_value=ptr_shared(); - if (value) { - new_value = share_string(value); + if (cleaned_value) { + new_value = share_string(cleaned_value); tracker.set(*this, key, new_value); if (!existing) { if (ref) { @@ -355,7 +399,11 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ if ( new_value != old_value && (!old_value || !new_value || strcmp(old_value, new_value))) { _document->logger()->notifyAttributeChanged(*this, key, old_value, new_value); _observers.notifyAttributeChanged(*this, key, old_value, new_value); + //g_warning( "setAttribute notified: %s: %s: %s: %s", name, element.c_str(), old_value, new_value ); } + + g_free( cleaned_value ); + } void SimpleNode::addChild(Node *generic_child, Node *generic_ref) { -- cgit v1.2.3 From 568092089e052882df7f160a3ba8bec9e275c437 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 4 Dec 2011 11:10:12 +0100 Subject: cppcheck (bzr r10759) --- src/xml/repr-io.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/xml') diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 39eb2637a..7252845b1 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -82,6 +82,10 @@ public: instr(0), gzin(0) { + for (int k=0;k<4;k++) + { + firstFew[k]=0; + } } virtual ~XmlSource() { -- cgit v1.2.3 From 4e51446f417ad82d2cdac758d0c5ce908ff88038 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 8 Dec 2011 11:53:54 +0000 Subject: Switch to top-level glib headers. Thanks to DimStar for patch Fixed bugs: - https://launchpad.net/bugs/898538 (bzr r10762) --- src/xml/attribute-record.h | 3 +-- src/xml/comment-node.h | 2 +- src/xml/croco-node-iface.cpp | 2 +- src/xml/event.h | 3 +-- src/xml/node-event-vector.h | 2 +- src/xml/node-observer.h | 2 +- src/xml/node.h | 2 +- src/xml/pi-node.h | 2 +- src/xml/quote.cpp | 2 +- src/xml/rebase-hrefs.cpp | 4 +--- src/xml/rebase-hrefs.h | 2 +- src/xml/repr.h | 2 +- src/xml/simple-node.cpp | 2 +- src/xml/text-node.h | 2 +- 14 files changed, 14 insertions(+), 18 deletions(-) (limited to 'src/xml') diff --git a/src/xml/attribute-record.h b/src/xml/attribute-record.h index bab0b5aa4..a61329b83 100644 --- a/src/xml/attribute-record.h +++ b/src/xml/attribute-record.h @@ -5,8 +5,7 @@ #ifndef SEEN_XML_SP_REPR_ATTR_H #define SEEN_XML_SP_REPR_ATTR_H -#include -#include +#include #include "gc-managed.h" #include "util/share.h" diff --git a/src/xml/comment-node.h b/src/xml/comment-node.h index 2232fb61e..56b8ad476 100644 --- a/src/xml/comment-node.h +++ b/src/xml/comment-node.h @@ -15,7 +15,7 @@ #ifndef SEEN_INKSCAPE_XML_COMMENT_NODE_H #define SEEN_INKSCAPE_XML_COMMENT_NODE_H -#include +#include #include "xml/simple-node.h" namespace Inkscape { diff --git a/src/xml/croco-node-iface.cpp b/src/xml/croco-node-iface.cpp index 72bcba7f3..6bd5a6920 100644 --- a/src/xml/croco-node-iface.cpp +++ b/src/xml/croco-node-iface.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include "xml/croco-node-iface.h" #include "xml/node.h" diff --git a/src/xml/event.h b/src/xml/event.h index c2865b8c4..55e2add88 100644 --- a/src/xml/event.h +++ b/src/xml/event.h @@ -18,8 +18,7 @@ #ifndef SEEN_INKSCAPE_XML_SP_REPR_ACTION_H #define SEEN_INKSCAPE_XML_SP_REPR_ACTION_H -#include -#include +#include #include #include diff --git a/src/xml/node-event-vector.h b/src/xml/node-event-vector.h index 0c291c230..e6396877d 100644 --- a/src/xml/node-event-vector.h +++ b/src/xml/node-event-vector.h @@ -14,7 +14,7 @@ #ifndef SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR #define SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR -#include +#include #include "xml/node.h" diff --git a/src/xml/node-observer.h b/src/xml/node-observer.h index 59142be8c..d0c85d1dd 100644 --- a/src/xml/node-observer.h +++ b/src/xml/node-observer.h @@ -18,7 +18,7 @@ #ifndef SEEN_INKSCAPE_XML_NODE_OBSERVER_H #define SEEN_INKSCAPE_XML_NODE_OBSERVER_H -#include +#include #include "util/share.h" #ifndef INK_UNUSED diff --git a/src/xml/node.h b/src/xml/node.h index 8b7dea203..c11f2fbdf 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -18,7 +18,7 @@ #ifndef SEEN_INKSCAPE_XML_NODE_H #define SEEN_INKSCAPE_XML_NODE_H -#include +#include #include "gc-anchored.h" #include "util/list.h" diff --git a/src/xml/pi-node.h b/src/xml/pi-node.h index e1f59ab27..1f892f97a 100644 --- a/src/xml/pi-node.h +++ b/src/xml/pi-node.h @@ -14,7 +14,7 @@ #ifndef SEEN_INKSCAPE_XML_PI_NODE_H #define SEEN_INKSCAPE_XML_PI_NODE_H -#include +#include #include "xml/simple-node.h" namespace Inkscape { diff --git a/src/xml/quote.cpp b/src/xml/quote.cpp index e569ed818..51f9ffb97 100644 --- a/src/xml/quote.cpp +++ b/src/xml/quote.cpp @@ -12,7 +12,7 @@ */ #include -#include +#include /** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc). diff --git a/src/xml/rebase-hrefs.cpp b/src/xml/rebase-hrefs.cpp index 4a7e050fa..9d4f4f9fc 100644 --- a/src/xml/rebase-hrefs.cpp +++ b/src/xml/rebase-hrefs.cpp @@ -7,9 +7,7 @@ #include "util/share.h" #include "xml/attribute-record.h" #include "xml/node.h" -#include -#include -#include +#include #include #include #include diff --git a/src/xml/rebase-hrefs.h b/src/xml/rebase-hrefs.h index 4cbdec9a5..adb09e52a 100644 --- a/src/xml/rebase-hrefs.h +++ b/src/xml/rebase-hrefs.h @@ -1,7 +1,7 @@ #ifndef REBASE_HREFS_H_SEEN #define REBASE_HREFS_H_SEEN -#include +#include #include "util/list.h" #include "xml/attribute-record.h" struct SPDocument; diff --git a/src/xml/repr.h b/src/xml/repr.h index 5fa9387c7..ffb8ab16b 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -15,7 +15,7 @@ #define SEEN_SP_REPR_H #include -#include +#include #include "gc-anchored.h" #include "xml/node.h" diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 44ddba237..c197d648b 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include "preferences.h" diff --git a/src/xml/text-node.h b/src/xml/text-node.h index 2fabd6953..53798b822 100644 --- a/src/xml/text-node.h +++ b/src/xml/text-node.h @@ -15,7 +15,7 @@ #ifndef SEEN_INKSCAPE_XML_TEXT_NODE_H #define SEEN_INKSCAPE_XML_TEXT_NODE_H -#include +#include #include "xml/simple-node.h" namespace Inkscape { -- cgit v1.2.3