diff options
| author | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-08-09 09:58:51 +0000 |
|---|---|---|
| committer | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-08-09 09:58:51 +0000 |
| commit | e5143d65bb57d4ce623e6220585b099e6d2ee453 (patch) | |
| tree | 4ff78f6fa8f0c1b740fd43b0ade2b91dbf9226d0 /src/sp-object.cpp | |
| parent | Remove deprecated Autotools and btool files. Please use CMake instead (diff) | |
| parent | Merged trunk (diff) | |
| download | inkscape-e5143d65bb57d4ce623e6220585b099e6d2ee453.tar.gz inkscape-e5143d65bb57d4ce623e6220585b099e6d2ee453.zip | |
Merged gsoc work. Created better data structure for selections, replaced SPObject children list, improved spray tool, split tests to separate executables
(bzr r15047)
Diffstat (limited to 'src/sp-object.cpp')
| -rw-r--r-- | src/sp-object.cpp | 187 |
1 files changed, 77 insertions, 110 deletions
diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 9cb386026..0cd7b371e 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -7,8 +7,9 @@ * Stephen Silver <sasilver@users.sourceforge.net> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 1999-2008 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -16,6 +17,7 @@ #include <cstring> #include <string> +#include <boost/range/adaptor/transformed.hpp> #include "helper/sp-marshal.h" #include "xml/node-event-vector.h" @@ -114,8 +116,7 @@ static gchar *sp_object_get_unique_id(SPObject *object, */ SPObject::SPObject() : cloned(0), uflags(0), mflags(0), hrefcount(0), _total_hrefcount(0), - document(NULL), parent(NULL), children(NULL), _last_child(NULL), - next(NULL), id(NULL), repr(NULL), refCount(1),hrefList(std::list<SPObject*>()), + document(NULL), parent(NULL), id(NULL), repr(NULL), refCount(1), hrefList(std::list<SPObject*>()), _successor(NULL), _collection_policy(SPObject::COLLECT_WITH_PARENT), _label(NULL), _default_label(NULL) { @@ -148,6 +149,9 @@ SPObject::~SPObject() { sp_object_unref(this->_successor, NULL); this->_successor = NULL; } + if (parent) { + parent->children.erase(parent->children.iterator_to(*this)); + } if( style == NULL ) { // style pointer could be NULL if unreffed too many times. @@ -396,13 +400,12 @@ void SPObject::changeCSS(SPCSSAttr *css, gchar const *attr) } std::vector<SPObject*> SPObject::childList(bool add_ref, Action) { - std::vector<SPObject*> l; - for ( SPObject *child = firstChild() ; child; child = child->getNext() ) { + std::vector<SPObject*> l; + for (auto& child: children) { if (add_ref) { - sp_object_ref (child); + sp_object_ref(&child); } - - l.push_back(child); + l.push_back(&child); } return l; @@ -465,9 +468,9 @@ void SPObject::requestOrphanCollection() { } void SPObject::_sendDeleteSignalRecursive() { - for (SPObject *child = firstChild(); child; child = child->getNext()) { - child->_delete_signal.emit(child); - child->_sendDeleteSignalRecursive(); + for (auto& child: children) { + child._delete_signal.emit(&child); + child._sendDeleteSignalRecursive(); } } @@ -495,12 +498,12 @@ void SPObject::deleteObject(bool propagate, bool propagate_descendants) void SPObject::cropToObject(SPObject *except) { std::vector<SPObject*> toDelete; - for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - if (child->isAncestorOf(except)) { - child->cropToObject(except); - } else if(child != except) { - toDelete.push_back(child); + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + if (child.isAncestorOf(except)) { + child.cropToObject(except); + } else if(&child != except) { + toDelete.push_back(&child); } } } @@ -523,60 +526,29 @@ void SPObject::attach(SPObject *object, SPObject *prev) object->parent = this; this->_updateTotalHRefCount(object->_total_hrefcount); - SPObject *next; - if (prev) { - next = prev->next; - prev->next = object; - } else { - next = this->children; - this->children = object; - } - object->next = next; - if (!next) { - this->_last_child = object; + auto it = children.begin(); + if (prev != nullptr) { + it = ++children.iterator_to(*prev); } + children.insert(it, *object); + if (!object->xml_space.set) object->xml_space.value = this->xml_space.value; } -void SPObject::reorder(SPObject *prev) -{ - //g_return_if_fail(object != NULL); - //g_return_if_fail(SP_IS_OBJECT(object)); - g_return_if_fail(this->parent != NULL); - g_return_if_fail(this != prev); - g_return_if_fail(!prev || SP_IS_OBJECT(prev)); - g_return_if_fail(!prev || prev->parent == this->parent); - - SPObject *const parent=this->parent; +void SPObject::reorder(SPObject* obj, SPObject* prev) { + g_return_if_fail(obj != nullptr); + g_return_if_fail(obj->parent); + g_return_if_fail(obj->parent == this); + g_return_if_fail(obj != prev); + g_return_if_fail(!prev || prev->parent == obj->parent); - SPObject *old_prev=NULL; - for ( SPObject *child = parent->children ; child && child != this ; - child = child->next ) - { - old_prev = child; + auto it = children.begin(); + if (prev != nullptr) { + it = ++children.iterator_to(*prev); } - SPObject *next=this->next; - if (old_prev) { - old_prev->next = next; - } else { - parent->children = next; - } - if (!next) { - parent->_last_child = old_prev; - } - if (prev) { - next = prev->next; - prev->next = this; - } else { - next = parent->children; - parent->children = this; - } - this->next = next; - if (!next) { - parent->_last_child = this; - } + children.splice(it, children, children.iterator_to(*obj)); } void SPObject::detach(SPObject *object) @@ -587,26 +559,9 @@ void SPObject::detach(SPObject *object) g_return_if_fail(SP_IS_OBJECT(object)); g_return_if_fail(object->parent == this); + children.erase(children.iterator_to(*object)); object->releaseReferences(); - SPObject *prev=NULL; - for ( SPObject *child = this->children ; child && child != object ; - child = child->next ) - { - prev = child; - } - - SPObject *next=object->next; - if (prev) { - prev->next = next; - } else { - this->children = next; - } - if (!next) { - this->_last_child = prev; - } - - object->next = NULL; object->parent = NULL; this->_updateTotalHRefCount(-object->_total_hrefcount); @@ -616,14 +571,14 @@ void SPObject::detach(SPObject *object) SPObject *SPObject::get_child_by_repr(Inkscape::XML::Node *repr) { g_return_val_if_fail(repr != NULL, NULL); - SPObject *result = 0; + SPObject *result = nullptr; - if ( _last_child && (_last_child->getRepr() == repr) ) { - result = _last_child; // optimization for common scenario + if (children.size() > 0 && children.back().getRepr() == repr) { + result = &children.back(); // optimization for common scenario } else { - for ( SPObject *child = children ; child ; child = child->next ) { - if ( child->getRepr() == repr ) { - result = child; + for (auto& child: children) { + if (child.getRepr() == repr) { + result = &child; break; } } @@ -654,10 +609,12 @@ void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) void SPObject::release() { SPObject* object = this; - debug("id=%p, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); - while (object->children) { - object->detach(object->children); + auto tmp = children | boost::adaptors::transformed([](SPObject& obj){return &obj;}); + std::vector<SPObject *> toRelease(tmp.begin(), tmp.end()); + + for (auto& p: toRelease) { + object->detach(p); } } @@ -678,7 +635,7 @@ void SPObject::order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node * / SPObject *ochild = object->get_child_by_repr(child); g_return_if_fail(ochild != NULL); SPObject *prev = new_ref ? object->get_child_by_repr(new_ref) : NULL; - ochild->reorder(prev); + object->reorder(ochild, prev); ochild->_position_changed_signal.emit(ochild); } @@ -840,15 +797,22 @@ void SPObject::releaseReferences() { SPObject *SPObject::getPrev() { - SPObject *prev = 0; - for ( SPObject *obj = parent->firstChild(); obj && !prev; obj = obj->getNext() ) { - if (obj->getNext() == this) { - prev = obj; - } + SPObject *prev = nullptr; + if (parent && !parent->children.empty() && &parent->children.front() != this) { + prev = &*(--parent->children.iterator_to(*this)); } return prev; } +SPObject* SPObject::getNext() +{ + SPObject *next = nullptr; + if (parent && !parent->children.empty() && &parent->children.back() != this) { + next = &*(++parent->children.iterator_to(*this)); + } + return next; +} + void SPObject::repr_child_added(Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data) { SPObject *object = SP_OBJECT(data); @@ -1512,8 +1476,11 @@ bool SPObject::setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool } else { // remove the current content of the 'text' or 'desc' element - SPObject *child; - while (NULL != (child = elem->firstChild())) child->deleteObject(); + auto tmp = elem->children | boost::adaptors::transformed([](SPObject& obj) { return &obj; }); + std::vector<SPObject*> vec(tmp.begin(), tmp.end()); + for (auto &child: vec) { + child->deleteObject(); + } } // add the new content @@ -1521,33 +1488,33 @@ bool SPObject::setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool return true; } -SPObject * SPObject::findFirstChild(gchar const *tagname) const +SPObject* SPObject::findFirstChild(gchar const *tagname) const { - for (SPObject *child = children; child; child = child->next) + for (auto& child: const_cast<SPObject*>(this)->children) { - if (child->repr->type() == Inkscape::XML::ELEMENT_NODE && - !strcmp(child->repr->name(), tagname)) { - return child; + if (child.repr->type() == Inkscape::XML::ELEMENT_NODE && + !strcmp(child.repr->name(), tagname)) { + return &child; } } - return NULL; + return nullptr; } char* SPObject::textualContent() const { GString* text = g_string_new(""); - for (const SPObject *child = firstChild(); child; child = child->next) + for (auto& child: children) { - Inkscape::XML::NodeType child_type = child->repr->type(); + Inkscape::XML::NodeType child_type = child.repr->type(); if (child_type == Inkscape::XML::ELEMENT_NODE) { - char* new_string = child->textualContent(); + char* new_string = child.textualContent(); g_string_append(text, new_string); g_free(new_string); } else if (child_type == Inkscape::XML::TEXT_NODE) { - g_string_append(text, child->repr->content()); + g_string_append(text, child.repr->content()); } } return g_string_free(text, FALSE); @@ -1564,8 +1531,8 @@ void SPObject::recursivePrintTree( unsigned level ) std::cout << " "; } std::cout << (getId()?getId():"No object id") << std::endl; - for (SPObject *child = children; child; child = child->next) { - child->recursivePrintTree( level+1 ); + for (auto& child: children) { + child.recursivePrintTree(level + 1); } } |
