Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

static void find_references ( SPObject elem,
refmap_type *  refmap 
) [static]

Build a table of places where IDs are referenced, for a given element. FIXME: There are some types of references not yet dealt with here (e.g., ID selectors in CSS stylesheets, and references in scripts).

Definition at line 88 of file id-clash.cpp.

References Inkscape::XML::Node::attribute(), Inkscape::XML::ELEMENT_NODE, SPStyle::filter, SPFilterReference::getObject(), SPPaintServerReference::getObject(), Inkscape::XML::Node::name(), paint(), and Inkscape::XML::Node::type().

Referenced by prevent_id_clashes().

{
    if (SP_OBJECT_IS_CLONED(elem)) return;
    Inkscape::XML::Node *repr_elem = SP_OBJECT_REPR(elem);
    if (!repr_elem) return;
    if (repr_elem->type() != Inkscape::XML::ELEMENT_NODE) return;

    /* check for references in inkscape:clipboard elements */
    if (!std::strcmp(repr_elem->name(), "inkscape:clipboard")) {
        SPCSSAttr *css = sp_repr_css_attr(repr_elem, "style");
        if (css) {
            for (unsigned i = 0; i < NUM_CLIPBOARD_PROPERTIES; ++i) {
                const char *attr = clipboard_properties[i];
                const gchar *value = sp_repr_css_property(css, attr, NULL);
                if (value) {
                    gchar *uri = extract_uri(value);
                    if (uri && uri[0] == '#') {
                        IdReference idref = { REF_CLIPBOARD, elem, attr };
                        (*refmap)[uri+1].push_back(idref);
                    }
                    g_free(uri);
                }
            }
        }
        return; // nothing more to do for inkscape:clipboard elements
    }

    /* check for xlink:href="#..." and similar */
    for (unsigned i = 0; i < NUM_HREF_LIKE_ATTRIBUTES; ++i) {
        const char *attr = href_like_attributes[i];
        const gchar *val = repr_elem->attribute(attr);
        if (val && val[0] == '#') {
            std::string id(val+1);
            IdReference idref = { REF_HREF, elem, attr };
            (*refmap)[id].push_back(idref);
        }
    }

    SPStyle *style = SP_OBJECT_STYLE(elem);

    /* check for url(#...) references in 'fill' or 'stroke' */
    for (unsigned i = 0; i < NUM_SPIPAINT_PROPERTIES; ++i) {
        const SPIPaint SPStyle::*prop = SPIPaint_members[i];
        const SPIPaint *paint = &(style->*prop);
        if (paint->isPaintserver() && paint->value.href) {
            const SPObject *obj = paint->value.href->getObject();
            if (obj) {
                const gchar *id = SP_OBJECT_ID(obj);
                IdReference idref = { REF_STYLE, elem, SPIPaint_properties[i] };
                (*refmap)[id].push_back(idref);
            }
        }
    }

    /* check for url(#...) references in 'filter' */
    const SPIFilter *filter = &(style->filter);
    if (filter->href) {
        const SPObject *obj = filter->href->getObject();
        if (obj) {
            const gchar *id = SP_OBJECT_ID(obj);
            IdReference idref = { REF_STYLE, elem, "filter" };
            (*refmap)[id].push_back(idref);
        }
    }

    /* check for other url(#...) references */
    for (unsigned i = 0; i < NUM_OTHER_URL_PROPERTIES; ++i) {
        const char *attr = other_url_properties[i];
        const gchar *value = repr_elem->attribute(attr);
        if (value) {
            gchar *uri = extract_uri(value);
            if (uri && uri[0] == '#') {
                IdReference idref = { REF_URL, elem, attr };
                (*refmap)[uri+1].push_back(idref);
            }
            g_free(uri);
        }
    }
    
    /* recurse */
    for (SPObject *child = sp_object_first_child(elem);
         child; child = SP_OBJECT_NEXT(child) )
    {
        find_references(child, refmap);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index