X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fxml%2Frepr-util.cpp;h=528902fef6505edc8609b29262f960465be0a5cf;hb=dc04c2a317d9e7ea799d78d5b4e9bf28997ca46f;hp=75ae692af5c39ba2291ac47ee508f6488e180087;hpb=6b15695578f07a3f72c4c9475c1a261a3021472a;p=inkscape.git diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 75ae692af..528902fef 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -20,16 +20,16 @@ #include #if HAVE_STRING_H -# include +# include #endif #if HAVE_STDLIB_H -# include +# include #endif #include - +#include <2geom/point.h> #include "svg/stringstream.h" #include "svg/css-ostringstream.h" @@ -149,7 +149,7 @@ static SPXMLNs *namespaces=NULL; static void sp_xml_ns_register_defaults() { - static SPXMLNs defaults[7]; + static SPXMLNs defaults[10]; defaults[0].uri = g_quark_from_static_string(SP_SODIPODI_NS_URI); defaults[0].prefix = g_quark_from_static_string("sodipodi"); @@ -177,7 +177,30 @@ sp_xml_ns_register_defaults() defaults[6].uri = g_quark_from_static_string(SP_DC_NS_URI); defaults[6].prefix = g_quark_from_static_string("dc"); - defaults[6].next = NULL; + defaults[6].next = &defaults[7]; + + // Inkscape versions prior to 0.44 would write this namespace + // URI instead of the correct sodipodi namespace; by adding this + // entry to the table last (where it gets used for URI -> prefix + // lookups, but not prefix -> URI lookups), we effectively transfer + // elements in this namespace to the correct sodipodi namespace: + + defaults[7].uri = g_quark_from_static_string(SP_BROKEN_SODIPODI_NS_URI); + defaults[7].prefix = g_quark_from_static_string("sodipodi"); + defaults[7].next = &defaults[8]; + + // "Duck prion" + // This URL became widespread due to a bug in versions <= 0.43 + + defaults[8].uri = g_quark_from_static_string("http://inkscape.sourceforge.net/DTD/s odipodi-0.dtd"); + defaults[8].prefix = g_quark_from_static_string("sodipodi"); + defaults[8].next = &defaults[9]; + + // This namespace URI is being phased out by Creative Commons + + defaults[9].uri = g_quark_from_static_string(SP_OLD_CC_NS_URI); + defaults[9].prefix = g_quark_from_static_string("cc"); + defaults[9].next = NULL; namespaces = &defaults[0]; } @@ -212,7 +235,6 @@ sp_xml_ns_auto_prefix(char const *uri) gchar const * sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested) { - SPXMLNs *iter; char const *prefix; if (!uri) return NULL; @@ -223,32 +245,46 @@ sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested) GQuark const key = g_quark_from_string(uri); prefix = NULL; - for ( iter = namespaces ; iter ; iter = iter->next ) { + for ( SPXMLNs *iter=namespaces ; iter ; iter = iter->next ) { if ( iter->uri == key ) { prefix = g_quark_to_string(iter->prefix); break; } } + if (!prefix) { - char const *new_prefix; + char *new_prefix; SPXMLNs *ns; if (suggested) { - new_prefix = suggested; + GQuark const prefix_key=g_quark_from_string(suggested); + + SPXMLNs *found=namespaces; + while ( found && found->prefix != prefix_key ) { + found = found->next; + } + + if (found) { // prefix already used? + new_prefix = sp_xml_ns_auto_prefix(uri); + } else { // safe to use suggested + new_prefix = g_strdup(suggested); + } } else { new_prefix = sp_xml_ns_auto_prefix(uri); } + ns = g_new(SPXMLNs, 1); - if (ns) { - ns->uri = g_quark_from_string(uri); - ns->prefix = g_quark_from_string(new_prefix); - ns->next = namespaces; - namespaces = ns; - prefix = g_quark_to_string(ns->prefix); - } - if (!suggested) { - g_free((char *)new_prefix); - } + g_assert( ns != NULL ); + ns->uri = g_quark_from_string(uri); + ns->prefix = g_quark_from_string(new_prefix); + + g_free(new_prefix); + + ns->next = namespaces; + namespaces = ns; + + prefix = g_quark_to_string(ns->prefix); } + return prefix; } @@ -289,7 +325,7 @@ double sp_repr_get_double_attribute(Inkscape::XML::Node *repr, char const *key, return g_ascii_strtod(result, NULL); } -int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *key, int def) +long long int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *key, long long int def) { char *result; @@ -300,7 +336,7 @@ int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *key, int de if (result == NULL) return def; - return atoi(result); + return atoll(result); } /** @@ -308,6 +344,7 @@ int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *key, int de * 0 positions are equivalent * 1 first object's position is greater than the second * -1 first object's position is less than the second + * @todo Rewrite this function's description to be understandable */ int sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second) @@ -361,7 +398,15 @@ sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second } /** - * lookup child by \a key, \a value. + * @brief 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. + * + * @param repr The node to start from + * @param key The name of the attribute to use for comparisons + * @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, @@ -381,11 +426,16 @@ sp_repr_lookup_child(Inkscape::XML::Node *repr, } /** - * \brief Recursively find the Inkscape::XML::Node matching the given XML name. - * \return A pointer to the matching Inkscape::XML::Node - * \param repr The Inkscape::XML::Node to start from - * \param name The desired XML name - * + * @brief Find an element node with the given name + * + * This function searches the descendants of the specified node depth-first for + * the first XML node with the specified name. + * + * @param repr The node to start from + * @param name The name of the element node to find + * @param maxdepth Maximum search depth, or -1 for an unlimited depth + * @return A pointer to the matching Inkscape::XML::Node + * @relatesalso Inkscape::XML::Node */ Inkscape::XML::Node * sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const *name, gint maxdepth ) @@ -409,6 +459,22 @@ sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const *name, gint maxdepth return found; } +/** + * Determine if the node is a 'title', 'desc' or 'metadata' element. + */ +bool +sp_repr_is_meta_element(const Inkscape::XML::Node *node) +{ + if (node == NULL) return false; + if (node->type() != Inkscape::XML::ELEMENT_NODE) return false; + gchar const *name = node->name(); + if (name == NULL) return false; + if (!std::strcmp(name, "svg:title")) return true; + if (!std::strcmp(name, "svg:desc")) return true; + if (!std::strcmp(name, "svg:metadata")) return true; + return false; +} + /** * Parses the boolean value of an attribute "key" in repr and sets val accordingly, or to FALSE if * the attr is not set. @@ -540,6 +606,41 @@ sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, double val) return true; } +unsigned sp_repr_set_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point const & val) +{ + g_return_val_if_fail(repr != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + + Inkscape::SVGOStringStream os; + os << val[Geom::X] << "," << val[Geom::Y]; + + repr->setAttribute(key, os.str().c_str()); + return true; +} + +unsigned int +sp_repr_get_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point *val) +{ + g_return_val_if_fail(repr != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(val != NULL, FALSE); + + gchar const *v = repr->attribute(key); + + gchar ** strarray = g_strsplit(v, ",", 2); + + if (strarray && strarray[0] && strarray[1]) { + double newx, newy; + newx = g_ascii_strtod(strarray[0], NULL); + newy = g_ascii_strtod(strarray[1], NULL); + g_strfreev (strarray); + *val = Geom::Point(newx, newy); + return TRUE; + } + + g_strfreev (strarray); + return FALSE; +} /* Local Variables: