diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-12-04 12:40:43 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-12-04 12:40:43 +0000 |
| commit | b0be54c82565f7e476187365ccb6c65d0729810d (patch) | |
| tree | c0b8133fa3a57934f4b57a5e5aaa5da0697864b0 /src | |
| parent | Minor comment/alignment changes. (diff) | |
| download | inkscape-b0be54c82565f7e476187365ccb6c65d0729810d.tar.gz inkscape-b0be54c82565f7e476187365ccb6c65d0729810d.zip | |
Add a few useful lookup functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xml/repr-css.cpp | 29 | ||||
| -rw-r--r-- | src/xml/repr-io.cpp | 6 | ||||
| -rw-r--r-- | src/xml/repr-util.cpp | 60 | ||||
| -rw-r--r-- | src/xml/repr.h | 20 |
4 files changed, 104 insertions, 11 deletions
diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 5db698406..d035b9a4b 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -61,7 +61,7 @@ protected: SimpleNode *_duplicate(Document* doc) const override { return new SPCSSAttrImpl(*this, doc); } }; -static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr); +static void sp_repr_css_add_components(SPCSSAttr *css, Node const *repr, gchar const *attr); /** * Creates an empty SPCSSAttr (a class for manipulating CSS style properties). @@ -90,7 +90,7 @@ void sp_repr_css_attr_unref(SPCSSAttr *css) * 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) +SPCSSAttr *sp_repr_css_attr(Node const *repr, gchar const *attr) { g_assert(repr != nullptr); g_assert(attr != nullptr); @@ -174,9 +174,9 @@ SPCSSAttr *sp_repr_css_attr_parse_color_to_fill(const Glib::ustring &text) /** * 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) +static void sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node const *repr, gchar const *attr) { - Node *parent = repr->parent(); + const Node *parent = repr->parent(); // read the ancestors from root down, using head recursion, so that children override parents if (parent) { @@ -188,7 +188,7 @@ static void sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node *repr, gch /** * Creates a new SPCSSAttr with one attribute whose value is determined by cascading. */ -SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) +SPCSSAttr *sp_repr_css_attr_inherited(Node const *repr, gchar const *attr) { g_assert(repr != nullptr); g_assert(attr != nullptr); @@ -205,7 +205,7 @@ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) * (nominally a style attribute). * */ -static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) +static void sp_repr_css_add_components(SPCSSAttr *css, Node const *repr, gchar const *attr) { g_assert(css != nullptr); g_assert(repr != nullptr); @@ -231,6 +231,23 @@ char const *sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const } /** + * Returns a character string of the value of a given style property or a default value if the + * attribute is not found. + */ +Glib::ustring sp_repr_css_property(SPCSSAttr *css, Glib::ustring const &name, Glib::ustring const &defval) +{ + g_assert(css != nullptr); + + Glib::ustring retval = defval; + char const *attr = ((Node *)css)->attribute(name.c_str()); + if (attr) { + retval = attr; + } + + return retval; +} + +/** * 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) diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index b1bf26118..c0ebfa12c 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -981,10 +981,9 @@ void sp_repr_write_stream_element( Node * repr, Writer & out, } out.printf( "<%s", element_name ); - // if this is a <text> element, suppress formatting whitespace + // If this is a <text> element, suppress formatting whitespace // for its content and children: - gchar const *xml_space_attr = repr->attribute("xml:space"); - if (xml_space_attr != nullptr && !strcmp(xml_space_attr, "preserve")) { + if (strcmp(repr->name(),"svg:text") == 0) { add_whitespace = false; } @@ -1014,6 +1013,7 @@ void sp_repr_write_stream_element( Node * repr, Writer & out, break; } } + if (repr->firstChild()) { out.writeChar('>'); if (loose && add_whitespace) { diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index a5dea02a2..a02997105 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -21,6 +21,8 @@ #include <glib.h> +#include <glibmm.h> + #include <2geom/point.h> #include "svg/stringstream.h" #include "svg/css-ostringstream.h" @@ -334,6 +336,36 @@ Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr, return nullptr; } +/** + * Recursive version of sp_repr_lookup_child(). + */ +Inkscape::XML::Node const *sp_repr_lookup_descendant(Inkscape::XML::Node const *repr, + gchar const *key, + gchar const *value) +{ + Inkscape::XML::Node const *found = nullptr; + g_return_val_if_fail(repr != nullptr, NULL); + gchar const *repr_value = repr->attribute(key); + if ( (repr_value == value) || + (repr_value && value && strcmp(repr_value, value) == 0) ) { + found = repr; + } else { + for (Inkscape::XML::Node const *child = repr->firstChild() ; child && !found; child = child->next() ) { + found = sp_repr_lookup_descendant( child, key, value ); + } + } + return found; +} + + +Inkscape::XML::Node *sp_repr_lookup_descendant(Inkscape::XML::Node *repr, + gchar const *key, + gchar const *value) +{ + Inkscape::XML::Node const *found = sp_repr_lookup_descendant( const_cast<Inkscape::XML::Node const *>(repr), key, value ); + return const_cast<Inkscape::XML::Node *>(found); +} + Inkscape::XML::Node const *sp_repr_lookup_name( Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth ) { Inkscape::XML::Node const *found = nullptr; @@ -391,6 +423,34 @@ std::vector<Inkscape::XML::Node const *> sp_repr_lookup_name_many( Inkscape::XML return nodes; } +std::vector<Inkscape::XML::Node *> +sp_repr_lookup_property_many( Inkscape::XML::Node *repr, Glib::ustring const& property, + Glib::ustring const &value, int maxdepth ) +{ + std::vector<Inkscape::XML::Node *> nodes; + std::vector<Inkscape::XML::Node *> found; + g_return_val_if_fail(repr != nullptr, nodes); + + SPCSSAttr* css = sp_repr_css_attr (repr, "style"); + if (value == sp_repr_css_property (css, property, "")) { + nodes.push_back(repr); + } + + if ( maxdepth != 0 ) { + // maxdepth == -1 means unlimited + if ( maxdepth == -1 ) { + maxdepth = 0; + } + + for (Inkscape::XML::Node *child = repr->firstChild() ; child; child = child->next() ) { + found = sp_repr_lookup_property_many( child, property, value, maxdepth - 1); + nodes.insert(nodes.end(), found.begin(), found.end()); + } + } + + return nodes; +} + /** * Determine if the node is a 'title', 'desc' or 'metadata' element. */ diff --git a/src/xml/repr.h b/src/xml/repr.h index 1c3bf1193..e9f01c5d4 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -78,12 +78,13 @@ bool sp_repr_save_rebased_file(Inkscape::XML::Document *doc, char const *filenam SPCSSAttr *sp_repr_css_attr_new(); void sp_repr_css_attr_unref(SPCSSAttr *css); -SPCSSAttr *sp_repr_css_attr(Inkscape::XML::Node *repr, char const *attr); +SPCSSAttr *sp_repr_css_attr(Inkscape::XML::Node const *repr, char const *attr); SPCSSAttr *sp_repr_css_attr_parse_color_to_fill(const Glib::ustring &text); -SPCSSAttr *sp_repr_css_attr_inherited(Inkscape::XML::Node *repr, char const *attr); +SPCSSAttr *sp_repr_css_attr_inherited(Inkscape::XML::Node const *repr, char const *attr); SPCSSAttr *sp_repr_css_attr_unset_all(SPCSSAttr *css); char const *sp_repr_css_property(SPCSSAttr *css, char const *name, char const *defval); +Glib::ustring sp_repr_css_property(SPCSSAttr *css, Glib::ustring const &name, Glib::ustring const &defval); void sp_repr_css_set_property(SPCSSAttr *css, char const *name, char const *value); void sp_repr_css_unset_property(SPCSSAttr *css, char const *name); bool sp_repr_css_property_is_unset(SPCSSAttr *css, char const *name); @@ -151,10 +152,25 @@ std::vector<Inkscape::XML::Node const *> sp_repr_lookup_name_many(Inkscape::XML: char const *name, int maxdepth = -1); +// Find an element node using an unique attribute. Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr, char const *key, char const *value); +// Find an element node using an unique attribute recursively. +Inkscape::XML::Node *sp_repr_lookup_descendant(Inkscape::XML::Node *repr, + char const *key, + char const *value); + +Inkscape::XML::Node const *sp_repr_lookup_descendant(Inkscape::XML::Node const *repr, + char const *key, + char const *value); + +// Find element nodes using a property value. +std::vector<Inkscape::XML::Node *> sp_repr_lookup_property_many(Inkscape::XML::Node *repr, + Glib::ustring const &property, + Glib::ustring const &value, + int maxdepth = -1); inline Inkscape::XML::Node *sp_repr_document_first_child(Inkscape::XML::Document const *doc) { return const_cast<Inkscape::XML::Node *>(doc->firstChild()); |
