X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fxml%2Frepr-util.cpp;h=9405cde0186a63e57ced039c34786087b6f09536;hb=df44b6baca018000107cdde0c3613ff3bbc53742;hp=693558cf766ee07f19fcae63c89e5f5bd2f4cc5c;hpb=09484545541e5258d2cdd7e73a4b55d0687b76db;p=inkscape.git diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 693558cf7..9405cde01 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -1,5 +1,3 @@ -#define __SP_REPR_UTIL_C__ - /** \file * Miscellaneous helpers for reprs. */ @@ -7,6 +5,7 @@ /* * Authors: * Lauris Kaplinski + * Jon A. Cruz * * Copyright (C) 1999-2000 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. @@ -20,22 +19,26 @@ #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" #include "xml/repr.h" #include "xml/repr-sorting.h" + +#define OSB_NS_URI "http://www.openswatchbook.org/uri/2009/osb" + + struct SPXMLNs { SPXMLNs *next; unsigned int uri, prefix; @@ -149,7 +152,7 @@ static SPXMLNs *namespaces=NULL; static void sp_xml_ns_register_defaults() { - static SPXMLNs defaults[10]; + static SPXMLNs defaults[11]; defaults[0].uri = g_quark_from_static_string(SP_SODIPODI_NS_URI); defaults[0].prefix = g_quark_from_static_string("sodipodi"); @@ -179,28 +182,32 @@ sp_xml_ns_register_defaults() defaults[6].prefix = g_quark_from_static_string("dc"); 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].next = &defaults[8]; + // 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]; + defaults[8].uri = g_quark_from_static_string(SP_BROKEN_SODIPODI_NS_URI); + defaults[8].prefix = g_quark_from_static_string("sodipodi"); + defaults[8].next = &defaults[9]; // "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]; + 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].next = &defaults[10]; // 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; + defaults[10].uri = g_quark_from_static_string(SP_OLD_CC_NS_URI); + defaults[10].prefix = g_quark_from_static_string("cc"); + defaults[10].next = NULL; namespaces = &defaults[0]; } @@ -344,9 +351,9 @@ long long int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *k * 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) +int sp_repr_compare_position(Inkscape::XML::Node const *first, Inkscape::XML::Node const *second) { int p1, p2; if (sp_repr_parent(first) == sp_repr_parent(second)) { @@ -359,7 +366,7 @@ sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second instance. */ // Find the lowest common ancestor(LCA) - Inkscape::XML::Node *ancestor = LCA(first, second); + Inkscape::XML::Node const *ancestor = LCA(first, second); g_assert(ancestor != NULL); if (ancestor == first) { @@ -397,7 +404,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, @@ -407,8 +422,8 @@ sp_repr_lookup_child(Inkscape::XML::Node *repr, g_return_val_if_fail(repr != NULL, NULL); for ( Inkscape::XML::Node *child = repr->firstChild() ; child ; child = child->next() ) { gchar const *child_value = child->attribute(key); - if ( child_value == value || - value && child_value && !strcmp(child_value, value) ) + if ( (child_value == value) || + (value && child_value && !strcmp(child_value, value)) ) { return child; } @@ -416,35 +431,51 @@ sp_repr_lookup_child(Inkscape::XML::Node *repr, return NULL; } -/** - * \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 - * - */ -Inkscape::XML::Node * -sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const *name, gint maxdepth ) +Inkscape::XML::Node const *sp_repr_lookup_name( Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth ) { + Inkscape::XML::Node const *found = 0; g_return_val_if_fail(repr != NULL, NULL); g_return_val_if_fail(name != NULL, NULL); GQuark const quark = g_quark_from_string(name); - if ( (GQuark)repr->code() == quark ) return repr; - if ( maxdepth == 0 ) return NULL; - - // maxdepth == -1 means unlimited - if ( maxdepth == -1 ) maxdepth = 0; + if ( (GQuark)repr->code() == quark ) { + found = repr; + } else if ( maxdepth != 0 ) { + // maxdepth == -1 means unlimited + if ( maxdepth == -1 ) { + maxdepth = 0; + } - Inkscape::XML::Node *found = NULL; - for (Inkscape::XML::Node *child = repr->firstChild() ; child && !found; child = child->next() ) { - found = sp_repr_lookup_name( child, name, maxdepth-1 ); + for (Inkscape::XML::Node const *child = repr->firstChild() ; child && !found; child = child->next() ) { + found = sp_repr_lookup_name( child, name, maxdepth - 1 ); + } } - return found; } +Inkscape::XML::Node *sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const *name, gint maxdepth ) +{ + Inkscape::XML::Node const *found = sp_repr_lookup_name( const_cast(repr), name, maxdepth ); + return const_cast(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. @@ -576,6 +607,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: @@ -586,4 +652,4 @@ sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, double val) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :