diff options
| author | Andrew Higginson <at.higginson@gmail.com> | 2011-12-27 21:04:47 +0000 |
|---|---|---|
| committer | Andrew <at.higginson@gmail.com> | 2011-12-27 21:04:47 +0000 |
| commit | 80960b623a99aae1402ab651b2974ef544ed3b03 (patch) | |
| tree | ba49d42c2789e9e11f805e2d5263e10f9fedeef8 /src/xml/repr-css.cpp | |
| parent | try to fix bug (diff) | |
| parent | GDL: Cherry-pick upstream patch 73852 (2011-03-23) - Add missing return value. (diff) | |
| download | inkscape-80960b623a99aae1402ab651b2974ef544ed3b03.tar.gz inkscape-80960b623a99aae1402ab651b2974ef544ed3b03.zip | |
merged with trunk so I can build again...
(bzr r10092.1.36)
Diffstat (limited to 'src/xml/repr-css.cpp')
| -rw-r--r-- | src/xml/repr-css.cpp | 115 |
1 files changed, 109 insertions, 6 deletions
diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index dc6494bcd..ced4f5da4 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -1,11 +1,28 @@ /* * bulia byak <buliabyak@users.sf.net> -*/ + * Tavmjong Bah <tavmjong@free.fr> (Documentation) + * + * Functions to manipulate SPCSSAttr which is a class derived from Inkscape::XML::Node See + * sp-css-attr.h and node.h + * + * SPCSSAttr is a special node type where the "attributes" are the properties in an element's style + * attribute. For example, style="fill:blue;stroke:none" is stored in a List (Inkscape::Util:List) + * where the key is the property (e.g. "fill" or "stroke") and the value is the property's value + * (e.g. "blue" or "none"). An element's properties are manipulated by adding, removing, or + * changing an item in the List. Utility functions are provided to go back and forth between the + * two ways of representing properties (by a string or by a list). + * + * Use sp_repr_write_string to go from a property list to a style string. + * + */ #define SP_REPR_CSS_C #include <cstring> +#include <string> +#include <sstream> #include <glibmm/ustring.h> +#include "svg/css-ostringstream.h" #include "xml/repr.h" #include "xml/simple-document.h" @@ -35,7 +52,9 @@ protected: static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr); - +/** + * Creates an empty SPCSSAttr (a class for manipulating CSS style properties). + */ SPCSSAttr * sp_repr_css_attr_new() { @@ -46,6 +65,9 @@ sp_repr_css_attr_new() return new SPCSSAttrImpl(attr_doc); } +/** + * Unreferences an SPCSSAttr (will be garbage collected if no references remain). + */ void sp_repr_css_attr_unref(SPCSSAttr *css) { @@ -53,6 +75,12 @@ sp_repr_css_attr_unref(SPCSSAttr *css) Inkscape::GC::release((Node *) css); } +/** + * Creates a new SPCSSAttr with one attribute (i.e. style) copied from an existing repr (node). The + * repr attribute data is in the form of a char const * string (e.g. fill:#00ff00;stroke:none). The + * 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) { g_assert(repr != NULL); @@ -63,6 +91,9 @@ SPCSSAttr *sp_repr_css_attr(Node *repr, gchar const *attr) return css; } +/** + * 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) { @@ -72,11 +103,12 @@ sp_repr_css_attr_inherited_recursive(SPCSSAttr *css, Node *repr, gchar const *at if (parent) { sp_repr_css_attr_inherited_recursive(css, parent, attr); } - sp_repr_css_add_components(css, repr, attr); } - +/** + * Creates a new SPCSSAttr with one attribute whose value is determined by cascading. + */ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) { g_assert(repr != NULL); @@ -89,6 +121,11 @@ SPCSSAttr *sp_repr_css_attr_inherited(Node *repr, gchar const *attr) return css; } +/** + * Adds components (style properties) to an existing SPCSAttr from the specified attribute's data + * (nominally a style attribute). + * + */ static void sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) { @@ -100,6 +137,10 @@ sp_repr_css_add_components(SPCSSAttr *css, Node *repr, gchar const *attr) sp_repr_css_attr_add_from_string(css, data); } +/** + * Returns a character string of the value of a given style property or a default value if the + * attribute is not found. + */ char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval) { @@ -112,6 +153,9 @@ sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval) : attr ); } +/** + * 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) { @@ -123,6 +167,9 @@ sp_repr_css_property_is_unset(SPCSSAttr *css, gchar const *name) } +/** + * Set a style property to a new value (e.g. fill to #ffff00). + */ void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value) { @@ -132,6 +179,9 @@ sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value) ((Node *) css)->setAttribute(name, value, false); } +/** + * Set a style property to "inkscape:unset". + */ void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name) { @@ -141,6 +191,9 @@ sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name) ((Node *) css)->setAttribute(name, "inkscape:unset", false); } +/** + * Return the value of a style property if property define, or a default value if not. + */ double sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval) { @@ -150,6 +203,9 @@ sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval) return sp_repr_get_double_attribute((Node *) css, name, defval); } +/** + * Write a style attribute string from a list of properties stored in an SPCSAttr object. + */ gchar * sp_repr_css_write_string(SPCSSAttr *css) { @@ -186,6 +242,9 @@ sp_repr_css_write_string(SPCSSAttr *css) return (buffer.empty() ? NULL : g_strdup (buffer.c_str())); } +/** + * Sets an attribute (e.g. style) to a string created from a list of style properties. + */ void sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) { @@ -195,11 +254,20 @@ sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr) gchar *value = sp_repr_css_write_string(css); + /* + * If the new value is different from the old value, this will sometimes send a signal via + * CompositeNodeObserver::notiftyAttributeChanged() which results in calling + * SPObject::sp_object_repr_attr_changed and thus updates the object's SPStyle. This update + * results in another call to repr->setAttribute(). + */ repr->setAttribute(attr, value); if (value) g_free (value); } +/** + * Loops through a List of style properties, printing key/value pairs. + */ void sp_repr_css_print(SPCSSAttr *css) { @@ -212,6 +280,9 @@ sp_repr_css_print(SPCSSAttr *css) } } +/** + * Merges two SPCSSAttr's. Properties in src overwrite properties in dst if present in both. + */ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) { @@ -221,19 +292,42 @@ sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) dst->mergeFrom(src, ""); } - +/** + * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + */ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { guchar *const str_value_unsigned = cr_term_to_string(decl->value); gchar *const str_value = reinterpret_cast<gchar *>(str_value_unsigned); gchar *value_unquoted = attribute_unquote (str_value); // libcroco returns strings quoted in "" - ((Node *) css)->setAttribute(decl->property->stryng->str, value_unquoted, false); + + // libcroco uses %.17f for formatting... leading to trailing zeros or small rounding errors. + // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has + // the additional benefit of respecting the numerical precission set in the SVG Output + // preferences. We assume any numerical part comes first (if not, the whole string is copied). + std::stringstream ss( value_unquoted ); + double number = 0; + std::string characters; + std::string temp; + bool number_valid = !(ss >> number).fail(); + if( !number_valid ) ss.clear(); + while( !(ss >> temp).eof() ) { + characters += temp; + characters += " "; + } + characters += temp; + Inkscape::CSSOStringStream os; + if( number_valid ) os << number; + os << characters; + ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); g_free(value_unquoted); g_free(str_value); } /** + * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + * * \pre decl_list != NULL */ static void @@ -248,6 +342,10 @@ sp_repr_css_merge_from_decl_list(SPCSSAttr *css, CRDeclaration const *const decl } } +/** + * Use libcroco to parse a string for CSS properties and then merge + * them into an existing SPCSSAttr. + */ void sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p) { @@ -261,6 +359,11 @@ sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p) } } +/** + * Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given + * SPCSAttr, and then replaces that SPCSAttr with the new one. This is called, for example, for + * each object in turn when a selection's style is updated via sp_desktop_set_style(). + */ void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr) { |
