From 6ed2673499ca548767bb7d2edb453a228ece86fd Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 12 Jun 2016 10:25:42 +0200 Subject: Optionally sort attributes and properties into a canonical order. Useful for comparing different versions of an SVG file. (bzr r14980) --- src/attribute-sort-util.cpp | 206 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 src/attribute-sort-util.cpp (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp new file mode 100644 index 000000000..ef08a142f --- /dev/null +++ b/src/attribute-sort-util.cpp @@ -0,0 +1,206 @@ +/* + * attribute-sort-util.cpp + * + * Created on: Jun 10, 2016 + * Author: Tavmjong Bah + */ + +/** + * Utility functions for sorting attributes by name. + */ + +#include +#include +#include +#include +#include +#include // std::pair +#include // std::sort + +#include "attribute-sort-util.h" + +#include "xml/repr.h" +#include "xml/attribute-record.h" +#include "xml/sp-css-attr.h" + +#include "attributes.h" + +using Inkscape::XML::Node; +using Inkscape::XML::AttributeRecord; +using Inkscape::Util::List; + +/** + * Sort attributes by name. + */ +void sp_attribute_sort_tree(Node *repr) { + + g_return_if_fail (repr != NULL); + + sp_attribute_sort_recursive( repr ); +} + +/** + * Sort recursively over all elements. + */ +void sp_attribute_sort_recursive(Node *repr) { + + g_return_if_fail (repr != NULL); + + if( repr->type() == Inkscape::XML::ELEMENT_NODE ) { + Glib::ustring element = repr->name(); + + // Only sort elements in svg namespace + if( element.substr(0,4) == "svg:" ) { + sp_attribute_sort_element( repr ); + } + } + + for(Node *child=repr->firstChild() ; child ; child = child->next()) { + sp_attribute_sort_recursive( child ); + } +} + +/** + * Compare function + */ +bool cmp(std::pair< Glib::ustring, Glib::ustring > const &a, + std::pair< Glib::ustring, Glib::ustring > const &b) { + unsigned val_b = sp_attribute_lookup(b.first.c_str()); + if (val_b == 0) return true; // Unknown attributes at end. + return sp_attribute_lookup(a.first.c_str()) < val_b; +} + +/** + * Sort attributes on an element + */ +void sp_attribute_sort_element(Node *repr) { + + g_return_if_fail (repr != NULL); + g_return_if_fail (repr->type() == Inkscape::XML::ELEMENT_NODE); + + // Glib::ustring element = repr->name(); + // Glib::ustring id = (repr->attribute( "id" )==NULL ? "" : repr->attribute( "id" )); + + sp_attribute_sort_style(repr); + + // Sort attributes: + + // It doesn't seem possible to sort a List directly so we dump the list into + // a std::list and sort that. Not very efficient. Sad. + List attributes = repr->attributeList(); + + std::vector > my_list; + for ( List iter = attributes ; iter ; ++iter ) { + + Glib::ustring attribute = g_quark_to_string(iter->key); + Glib::ustring value = (const char*)iter->value; + + // C++11 my_list.emlace_back(attribute, value); + my_list.push_back(std::make_pair(attribute,value)); + } + std::sort(my_list.begin(), my_list.end(), cmp); + // Delete all attributes. + //for (auto it: my_list) { + for (std::vector >::iterator it = my_list.begin(); + it != my_list.end(); ++it) { + repr->setAttribute( it->first.c_str(), NULL, false ); + } + // Insert all attributes in proper order + for (std::vector >::iterator it = my_list.begin(); + it != my_list.end(); ++it) { + repr->setAttribute( it->first.c_str(), it->second.c_str(), false ); + } +} + + +/** + * Sort CSS style on an element. + */ +void sp_attribute_sort_style(Node *repr) { + + g_return_if_fail (repr != NULL); + g_return_if_fail (repr->type() == Inkscape::XML::ELEMENT_NODE); + + // Find element's style + SPCSSAttr *css = sp_repr_css_attr( repr, "style" ); + sp_attribute_sort_style(repr, css); + + // Convert css node's properties data to string and set repr node's attribute "style" to that string. + // sp_repr_css_set( repr, css, "style"); // Don't use as it will cause loop. + Glib::ustring value; + sp_repr_css_write_string(css, value); + if( value.empty() ) { + repr->setAttribute("style", NULL ); + } else { + repr->setAttribute("style", value.c_str()); + } + + sp_repr_css_attr_unref( css ); +} + + +/** + * Sort CSS style on an element. + */ +Glib::ustring sp_attribute_sort_style(Node *repr, gchar const *string) { + + g_return_val_if_fail (repr != NULL, NULL); + g_return_val_if_fail (repr->type() == Inkscape::XML::ELEMENT_NODE, NULL); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_attr_add_from_string( css, string ); + sp_attribute_sort_style(repr, css); + Glib::ustring string_cleaned; + sp_repr_css_write_string (css, string_cleaned); + + sp_repr_css_attr_unref( css ); + + return string_cleaned; +} + + +/** + * Sort CSS style on an element. + */ +void sp_attribute_sort_style(Node* repr, SPCSSAttr *css) { + + g_return_if_fail (repr != NULL); + g_return_if_fail (css != NULL); + + Glib::ustring element = repr->name(); + Glib::ustring id = (repr->attribute( "id" )==NULL ? "" : repr->attribute( "id" )); + + // Loop over all properties in "style" node. + std::vector > my_list; + for ( List iter = css->attributeList() ; iter ; ++iter ) { + + Glib::ustring property = g_quark_to_string(iter->key); + Glib::ustring value = (const char*)iter->value; + + // C++11 my_list.emlace_back(property, value); + my_list.push_back(std::make_pair(property,value)); + } + std::sort(my_list.begin(), my_list.end(), cmp); + // Delete all attributes. + //for (auto it: my_list) { + for (std::vector >::iterator it = my_list.begin(); + it != my_list.end(); ++it) { + sp_repr_css_set_property( css, it->first.c_str(), NULL ); + } + // Insert all attributes in proper order + for (std::vector >::iterator it = my_list.begin(); + it != my_list.end(); ++it) { + sp_repr_css_set_property( css, it->first.c_str(), it->second.c_str() ); + } +} + +/* + 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 : -- cgit v1.2.3 From 51cd1dfb720642e51b811558ddead6cd47ceee0f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 12 Jun 2016 20:08:22 +0200 Subject: Fix faulty comparison function. (bzr r14983) --- src/attribute-sort-util.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp index ef08a142f..d0f45c418 100644 --- a/src/attribute-sort-util.cpp +++ b/src/attribute-sort-util.cpp @@ -65,9 +65,11 @@ void sp_attribute_sort_recursive(Node *repr) { */ bool cmp(std::pair< Glib::ustring, Glib::ustring > const &a, std::pair< Glib::ustring, Glib::ustring > const &b) { + unsigned val_a = sp_attribute_lookup(a.first.c_str()); unsigned val_b = sp_attribute_lookup(b.first.c_str()); - if (val_b == 0) return true; // Unknown attributes at end. - return sp_attribute_lookup(a.first.c_str()) < val_b; + if (val_a == 0) return false; // Unknown attributes at end. + if (val_b == 0) return true; // Unknown attributes at end. + return val_a < val_b; } /** -- cgit v1.2.3 From f5c74e3a9d4e23e6cc86851b426dd05958e907ee Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 4 Jul 2016 14:30:44 +0200 Subject: Prevent data-losing crash when sorting attributes and Layer dialog open. (bzr r15007) --- src/attribute-sort-util.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp index d0f45c418..5c01f7914 100644 --- a/src/attribute-sort-util.cpp +++ b/src/attribute-sort-util.cpp @@ -105,12 +105,17 @@ void sp_attribute_sort_element(Node *repr) { //for (auto it: my_list) { for (std::vector >::iterator it = my_list.begin(); it != my_list.end(); ++it) { - repr->setAttribute( it->first.c_str(), NULL, false ); + // Removing "inkscape:label" results in crash when Layers dialog is open. + if (it->first != "inkscape:label") { + repr->setAttribute( it->first.c_str(), NULL, false ); + } } // Insert all attributes in proper order for (std::vector >::iterator it = my_list.begin(); it != my_list.end(); ++it) { - repr->setAttribute( it->first.c_str(), it->second.c_str(), false ); + if (it->first != "inkscape:label") { + repr->setAttribute( it->first.c_str(), it->second.c_str(), false ); + } } } -- cgit v1.2.3 From f35bb1f74a0ffeb5c6477a25e3c4cde87a97bcf1 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 12:06:06 +0200 Subject: Removed unused includes, decrease compilation time (bzr r15025) --- src/attribute-sort-util.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp index 5c01f7914..7aa8d8357 100644 --- a/src/attribute-sort-util.cpp +++ b/src/attribute-sort-util.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include #include // std::pair @@ -21,7 +20,6 @@ #include "xml/repr.h" #include "xml/attribute-record.h" -#include "xml/sp-css-attr.h" #include "attributes.h" -- cgit v1.2.3 From 43b49e325db73cc19b1731db6c69545664ee8fbe Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 13:26:17 +0200 Subject: Reverted changes to r15024 after many building problems (bzr r15027) --- src/attribute-sort-util.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp index 7aa8d8357..5c01f7914 100644 --- a/src/attribute-sort-util.cpp +++ b/src/attribute-sort-util.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include // std::pair @@ -20,6 +21,7 @@ #include "xml/repr.h" #include "xml/attribute-record.h" +#include "xml/sp-css-attr.h" #include "attributes.h" -- cgit v1.2.3 From 35830f456cadaecf8b8e3944e3031a1a93f6cb41 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 3 Aug 2016 15:29:38 +0200 Subject: Removed unused includes, decreased compilation time. Once again (bzr r15034) --- src/attribute-sort-util.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/attribute-sort-util.cpp') diff --git a/src/attribute-sort-util.cpp b/src/attribute-sort-util.cpp index 5c01f7914..7aa8d8357 100644 --- a/src/attribute-sort-util.cpp +++ b/src/attribute-sort-util.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include #include // std::pair @@ -21,7 +20,6 @@ #include "xml/repr.h" #include "xml/attribute-record.h" -#include "xml/sp-css-attr.h" #include "attributes.h" -- cgit v1.2.3