diff options
| author | MenTaLguY <mental@rydia.net> | 2006-01-16 02:36:01 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2006-01-16 02:36:01 +0000 |
| commit | 179fa413b047bede6e32109e2ce82437c5fb8d34 (patch) | |
| tree | a5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/xml/repr-css.cpp | |
| download | inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip | |
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/xml/repr-css.cpp')
| -rw-r--r-- | src/xml/repr-css.cpp | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp new file mode 100644 index 000000000..4953c2657 --- /dev/null +++ b/src/xml/repr-css.cpp @@ -0,0 +1,261 @@ +/* + * bulia byak <buliabyak@users.sf.net> +*/ + +#define SP_REPR_CSS_C + + +#include <glibmm/ustring.h> + +#include "xml/repr.h" +#include "xml/simple-node.h" + +using Inkscape::Util::List; +using Inkscape::XML::AttributeRecord; +using Inkscape::XML::SimpleNode; +using Inkscape::XML::Node; +using Inkscape::XML::NodeType; + +struct SPCSSAttrImpl : public SimpleNode, public SPCSSAttr { +public: + SPCSSAttrImpl() : SimpleNode(g_quark_from_static_string("css")) {} + + NodeType type() const { return Inkscape::XML::ELEMENT_NODE; } + +protected: + SimpleNode *_duplicate() const { return new SPCSSAttrImpl(*this); } +}; + +static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr); + +SPCSSAttr * +sp_repr_css_attr_new() +{ + return new SPCSSAttrImpl(); +} + +void +sp_repr_css_attr_unref(SPCSSAttr *css) +{ + g_assert(css != NULL); + Inkscape::GC::release((Node *) css); +} + +SPCSSAttr *sp_repr_css_attr(Node *repr, gchar const *attr) +{ + g_assert(repr != NULL); + g_assert(attr != NULL); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_add_components(css, repr, attr); + return css; +} + +SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) +{ + g_assert(repr != NULL); + g_assert(attr != NULL); + + SPCSSAttr *css = sp_repr_css_attr_new(); + + sp_repr_css_add_components(css, repr, attr); + Node *current = sp_repr_parent(repr); + + while (current) { + sp_repr_css_add_components(css, current, attr); + current = sp_repr_parent(current); + } + + return css; +} + +static void +sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) +{ + g_assert(css != NULL); + g_assert(repr != NULL); + g_assert(attr != NULL); + + char const *data = repr->attribute(attr); + sp_repr_css_attr_add_from_string(css, data); +} + +char const * +sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval) +{ + g_assert(css != NULL); + g_assert(name != NULL); + + char const *attr = ((Node *)css)->attribute(name); + return ( attr == NULL + ? defval + : attr ); +} + +bool +sp_repr_css_property_is_unset(SPCSSAttr *css, gchar const *name) +{ + g_assert(css != NULL); + g_assert(name != NULL); + + char const *attr = ((Node *)css)->attribute(name); + return (attr && !strcmp(attr, "inkscape:unset")); +} + + +void +sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value) +{ + g_assert(css != NULL); + g_assert(name != NULL); + + sp_repr_set_attr((Node *) css, name, value); +} + +void +sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name) +{ + g_assert(css != NULL); + g_assert(name != NULL); + + sp_repr_set_attr((Node *) css, name, "inkscape:unset"); +} + +double +sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval) +{ + g_assert(css != NULL); + g_assert(name != NULL); + + return sp_repr_get_double_attribute((Node *) css, name, defval); +} + +gchar * +sp_repr_css_write_string(SPCSSAttr *css) +{ + Glib::ustring buffer; + + for ( List<AttributeRecord const> iter = css->attributeList() ; + iter ; ++iter ) + { + if (iter->value && !strcmp(iter->value, "inkscape:unset")) { + continue; + } + + buffer.append(g_quark_to_string(iter->key)); + buffer.push_back(':'); + buffer.append(iter->value); + if (rest(iter)) { + buffer.push_back(';'); + } + } + + return (buffer.empty() ? NULL : g_strdup (buffer.c_str())); +} + +void +sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) +{ + g_assert(repr != NULL); + g_assert(css != NULL); + g_assert(attr != NULL); + + gchar *value = sp_repr_css_write_string(css); + + repr->setAttribute(attr, value); + + if (value) g_free (value); +} + +void +sp_repr_css_print(SPCSSAttr *css) +{ + for ( List<AttributeRecord const> iter = css->attributeList() ; + iter ; ++iter ) + { + g_print(g_quark_to_string(iter->key)); + g_print(":\t"); + g_print(iter->value); + g_print("\n"); + } +} + +void +sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) +{ + g_assert(dst != NULL); + g_assert(src != NULL); + + dst->mergeFrom(src, ""); +} + +void +sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *data) +{ + if (data != NULL) { + char *new_str = g_strdup(data); + char **token = g_strsplit(new_str, ";", 0); + for (char **ctoken = token; *ctoken != NULL; ctoken++) { + char *current = g_strstrip(*ctoken); + char *key = current; + char *val; + for (val = key; *val != '\0'; val++) + if (*val == ':') break; + if (*val == '\0') break; + *val++ = '\0'; + key = g_strstrip(key); + val = g_strstrip(val); + if (*val == '\0') break; + + /* fixme: CSS specifies that later declarations override earlier ones with the same + key. (Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.) + Either add a precondition that there are no key duplicates in the string, or get rid + of the below condition (documenting the change that data[] will override existing + values in *css), or process the list in reverse order. */ + if (!css->attribute(key)) + sp_repr_set_attr((Node *) css, key, val); + } + g_strfreev(token); + g_free(new_str); + } +} + +void +sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr) +{ + g_assert(repr != NULL); + g_assert(css != NULL); + g_assert(attr != NULL); + + SPCSSAttr *current = sp_repr_css_attr(repr, attr); + sp_repr_css_merge(current, css); + sp_repr_css_set(repr, current, attr); + + sp_repr_css_attr_unref(current); +} + +void +sp_repr_css_change_recursive(Node *repr, SPCSSAttr *css, gchar const *attr) +{ + g_assert(repr != NULL); + g_assert(css != NULL); + g_assert(attr != NULL); + + sp_repr_css_change(repr, css, attr); + + for (Node *child = repr->firstChild(); child != NULL; child = child->next()) { + sp_repr_css_change_recursive(child, css, attr); + } +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : |
