Logo Search packages:      
Sourcecode: inkscape version File versions

Inkscape::Util::List< AttributeRecord const > Inkscape::XML::rebase_href_attrs ( gchar const *const   old_abs_base,
gchar const *const   new_abs_base,
Inkscape::Util::List< AttributeRecord const >  attributes 
)

Change relative xlink:href attributes to be relative to new_abs_base instead of old_abs_base.

Note that old_abs_base and new_abs_base must each be non-NULL, absolute directory paths.

Definition at line 109 of file rebase-hrefs.cpp.

References Inkscape::Util::cons(), and sp_relative_path_from_path().

{
    using Inkscape::Util::List;
    using Inkscape::Util::cons;
    using Inkscape::Util::ptr_shared;
    using Inkscape::Util::share_string;

    if (old_abs_base == new_abs_base) {
        return attributes;
    }

    GQuark const href_key = g_quark_from_static_string("xlink:href");
    GQuark const absref_key = g_quark_from_static_string("sodipodi:absref");

    /* First search attributes for xlink:href and sodipodi:absref, putting the rest in ret.
     *
     * However, if we find that xlink:href doesn't need rebasing, then return immediately
     * with no change to attributes. */
    ptr_shared<char> old_href;
    ptr_shared<char> sp_absref;
    List<AttributeRecord const> ret;
    {
        for (List<AttributeRecord const> ai(attributes); ai; ++ai) {
            if (ai->key == href_key) {
                old_href = ai->value;
                if (!href_needs_rebasing(old_href)) {
                    return attributes;
                }
            } else if (ai->key == absref_key) {
                sp_absref = ai->value;
            } else {
                ret = cons(AttributeRecord(ai->key, ai->value), ret);
            }
        }
    }

    if (!old_href) {
        return attributes;
        /* We could instead return ret in this case, i.e. ensure that sodipodi:absref is cleared if
         * no xlink:href attribute.  However, retaining it might be more cautious.
         *
         * (For the usual case of not present, attributes and ret will be the same except
         * reversed.) */
    }

    gchar *const abs_href(calc_abs_href(old_abs_base, old_href, sp_absref));
    gchar const *const new_href = sp_relative_path_from_path(abs_href, new_abs_base);
    ret = cons(AttributeRecord(href_key, share_string(new_href)), ret);
    if (sp_absref) {
        /* We assume that if there wasn't previously a sodipodi:absref attribute
         * then we shouldn't create one. */
        ret = cons(AttributeRecord(absref_key, ( streq(abs_href, sp_absref)
                                                 ? sp_absref
                                                 : share_string(abs_href) )),
                   ret);
    }
    g_free(abs_href);
    return ret;
}


Generated by  Doxygen 1.6.0   Back to index