Index: src/path-chemistry.cpp =================================================================== --- src/path-chemistry.cpp (revision 21209) +++ src/path-chemistry.cpp (working copy) @@ -518,6 +518,10 @@ repr->setAttribute("style", style_str); g_free(style_str); + /* Custom attributes */ + sp_copy_custom_attributes(repr, SP_OBJECT_REPR(item)->attributeList()); + + /* Mask */ gchar *mask_str = (gchar *) SP_OBJECT_REPR(item)->attribute("mask"); if ( mask_str ) Index: src/splivarot.cpp =================================================================== --- src/splivarot.cpp (revision 21209) +++ src/splivarot.cpp (working copy) @@ -466,6 +466,8 @@ gchar const *style = repr_source->attribute("style"); gchar const *mask = repr_source->attribute("mask"); gchar const *clip_path = repr_source->attribute("clip-path"); + // remember everything to keep custom attributes + Inkscape::Util::List attrs = repr_source->attributeList(); gchar *title = source->title(); gchar *desc = source->desc(); // remove source paths @@ -520,6 +522,8 @@ repr->setAttribute("mask", mask); if (clip_path) repr->setAttribute("clip-path", clip_path); + + sp_copy_custom_attributes(repr, attrs); repr->setAttribute("d", d); g_free(d); @@ -569,6 +573,8 @@ if ( clip_path ) repr->setAttribute("clip-path", clip_path); + sp_copy_custom_attributes(repr, attrs); + repr->setAttribute("d", d); g_free(d); @@ -1872,7 +1878,6 @@ return p; } - /* Local Variables: mode:c++ Index: src/xml/repr.h =================================================================== --- src/xml/repr.h (revision 21209) +++ src/xml/repr.h (working copy) @@ -37,6 +37,7 @@ /* SPXMLNs */ char const *sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested); char const *sp_xml_ns_prefix_uri(gchar const *prefix); +bool sp_xml_ns_is_custom(gchar const *prefix); Inkscape::XML::Document *sp_repr_document_new(gchar const *rootname); @@ -120,7 +121,9 @@ } bool sp_repr_is_meta_element(const Inkscape::XML::Node *node); +void sp_copy_custom_attributes(Inkscape::XML::Node *new_node, Inkscape::Util::List attrs); + /* Convenience */ unsigned sp_repr_get_boolean(Inkscape::XML::Node *repr, gchar const *key, unsigned *val); unsigned sp_repr_get_int(Inkscape::XML::Node *repr, gchar const *key, int *val); Index: src/xml/repr-util.cpp =================================================================== --- src/xml/repr-util.cpp (revision 21209) +++ src/xml/repr-util.cpp (working copy) @@ -35,6 +35,7 @@ #include "xml/repr.h" #include "xml/repr-sorting.h" +#include "xml/attribute-record.h" #define OSB_NS_URI "http://www.openswatchbook.org/uri/2009/osb" @@ -43,6 +44,7 @@ struct SPXMLNs { SPXMLNs *next; unsigned int uri, prefix; + bool is_custom; }; /*##################### @@ -157,34 +159,42 @@ defaults[0].uri = g_quark_from_static_string(SP_SODIPODI_NS_URI); defaults[0].prefix = g_quark_from_static_string("sodipodi"); + defaults[0].is_custom = FALSE; defaults[0].next = &defaults[1]; defaults[1].uri = g_quark_from_static_string(SP_XLINK_NS_URI); defaults[1].prefix = g_quark_from_static_string("xlink"); + defaults[1].is_custom = FALSE; defaults[1].next = &defaults[2]; defaults[2].uri = g_quark_from_static_string(SP_SVG_NS_URI); defaults[2].prefix = g_quark_from_static_string("svg"); + defaults[2].is_custom = FALSE; defaults[2].next = &defaults[3]; defaults[3].uri = g_quark_from_static_string(SP_INKSCAPE_NS_URI); defaults[3].prefix = g_quark_from_static_string("inkscape"); + defaults[3].is_custom = FALSE; defaults[3].next = &defaults[4]; defaults[4].uri = g_quark_from_static_string(SP_RDF_NS_URI); defaults[4].prefix = g_quark_from_static_string("rdf"); + defaults[4].is_custom = FALSE; defaults[4].next = &defaults[5]; defaults[5].uri = g_quark_from_static_string(SP_CC_NS_URI); defaults[5].prefix = g_quark_from_static_string("cc"); + defaults[5].is_custom = FALSE; defaults[5].next = &defaults[6]; defaults[6].uri = g_quark_from_static_string(SP_DC_NS_URI); defaults[6].prefix = g_quark_from_static_string("dc"); + defaults[6].is_custom = FALSE; defaults[6].next = &defaults[7]; defaults[7].uri = g_quark_from_static_string(OSB_NS_URI); defaults[7].prefix = g_quark_from_static_string("osb"); + defaults[7].is_custom = FALSE; defaults[7].next = &defaults[8]; // Inkscape versions prior to 0.44 would write this namespace @@ -195,6 +205,7 @@ defaults[8].uri = g_quark_from_static_string(SP_BROKEN_SODIPODI_NS_URI); defaults[8].prefix = g_quark_from_static_string("sodipodi"); + defaults[8].is_custom = FALSE; defaults[8].next = &defaults[9]; // "Duck prion" @@ -202,12 +213,14 @@ defaults[9].uri = g_quark_from_static_string("http://inkscape.sourceforge.net/DTD/s odipodi-0.dtd"); defaults[9].prefix = g_quark_from_static_string("sodipodi"); + defaults[9].is_custom = FALSE; defaults[9].next = &defaults[10]; // This namespace URI is being phased out by Creative Commons defaults[10].uri = g_quark_from_static_string(SP_OLD_CC_NS_URI); defaults[10].prefix = g_quark_from_static_string("cc"); + defaults[10].is_custom = FALSE; defaults[10].next = NULL; namespaces = &defaults[0]; @@ -240,6 +253,20 @@ return new_prefix; } +bool +sp_xml_ns_is_custom(gchar const *prefix) +{ + SPXMLNs *iter; + GQuark const key = g_quark_from_string(prefix); + for ( iter = namespaces; iter ; iter = iter->next ) { + if ( iter->prefix == key ) { + return iter->is_custom; + } + } + + return TRUE; +} + gchar const * sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested) { @@ -284,6 +311,7 @@ g_assert( ns != NULL ); ns->uri = g_quark_from_string(uri); ns->prefix = g_quark_from_string(new_prefix); + ns->is_custom = TRUE; g_free(new_prefix); @@ -483,7 +511,33 @@ return false; } + /** + * Copy custom attributes (the ones with a non standart namespace). + */ +void sp_copy_custom_attributes(Inkscape::XML::Node *new_node, + Inkscape::Util::List attrs) +{ + // the custom attributes are the ones which have a non standart namespace + for ( ; attrs ; attrs++) { + const gchar *key = g_quark_to_string(attrs->key); + const gchar *prefix_end = strchr(key, ':'); + + if ( prefix_end != NULL ) { + const gchar *prefix = Glib::ustring(key, prefix_end).data(); + if ( sp_xml_ns_prefix_uri(prefix) == NULL ) { + // unknown prefix + new_node->setAttribute(key, attrs->value); + } else if ( sp_xml_ns_is_custom(prefix) == TRUE ) { + // not a standart one + new_node->setAttribute(key, attrs->value); + } + } + } +} + + +/** * Parses the boolean value of an attribute "key" in repr and sets val accordingly, or to FALSE if * the attr is not set. *