Code

Draw perspective lines for infinite VPs, too (they are updated during scrolling or...
[inkscape.git] / src / xml / node-fns.cpp
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
5 #include <map>
7 #include "xml/node-iterators.h"
8 #include "algorithms/find-if-before.h"
10 namespace Inkscape {
11 namespace XML {
13 /* the id_permitted stuff is a temporary-ish hack */
15 namespace {
17 bool id_permitted_internal(GQuark qname) {
18     char const *qname_s=g_quark_to_string(qname);
19     return !strncmp("svg:", qname_s, 4) || !strncmp("sodipodi:", qname_s, 9) ||
20            !strncmp("inkscape:", qname_s, 9);
21 }
24 bool id_permitted_internal_memoized(GQuark qname) {
25     typedef std::map<GQuark, bool> IdPermittedMap;
26     IdPermittedMap id_permitted_names;
28     IdPermittedMap::iterator found;
29     found = id_permitted_names.find(qname);
30     if ( found != id_permitted_names.end() ) {
31         return found->second;
32     } else {
33         bool permitted=id_permitted_internal(qname);
34         id_permitted_names[qname] = permitted;
35         return permitted;
36     }
37 }
39 }
41 bool id_permitted(Node const *node) {
42     g_return_val_if_fail(node != NULL, false);
44     if ( node->type() != ELEMENT_NODE ) {
45         return false;
46     }
48     return id_permitted_internal_memoized((GQuark)node->code());
49 }
51 struct node_matches {
52     node_matches(Node const &n) : node(n) {}
53     bool operator()(Node const &other) { return &other == &node; }
54     Node const &node;
55 };
57 /** Returns the sibling before \a node in \a node's parent's children,
58  *  or NULL if \a node is the first of those children (or if child is
59  *  NULL or has no parent).
60  *
61  *  Useful in combination with Node::addChild, when you want to insert
62  *  a new child _before_ a given existing child.
63  *
64  *  Note: Involves a linear search (unlike next_node).
65  *
66  * \pre Links are correct, i.e. \a node isin its parent's children.
67  *
68  * \post (ret == NULL
69  *        ? node == NULL || node->parent() == NULL || node->parent()->firstChild() == node
70  *        : ret->next() == node).
71  */
72 Node *previous_node(Node *node) {
73     using Inkscape::Algorithms::find_if_before;
75     if ( !node || !node->parent() ) {
76         return NULL;
77     }
79     Node *previous=find_if_before<NodeSiblingIterator>(
80         node->parent()->firstChild(), NULL, node_matches(*node)
81     );
83     g_assert(previous == NULL
84              ? node->parent()->firstChild() == node
85              : previous->next() == node);
87     return previous;
88 }
90 }
91 }
94 /*
95   Local Variables:
96   mode:c++
97   c-file-style:"stroustrup"
98   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
99   indent-tabs-mode:nil
100   fill-column:99
101   End:
102 */
103 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :