diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index bd4f664495f63b1e99f74138c63836fe9267e5e3..4cd1410f11b581697317ed1271705523361377d3 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -136,7 +136,12 @@ struct SPCanvasGroup { SPCanvasItem item; - std::list items; + // TODO: Consider refactoring the "items" structure to use map or set structure + // because std::deque is not optimal structure to use here. That is because + // canvas operations that need to find specific item from "items" become slow + // with very large path sets. This is evident e.g. in "path deselect" operation. + // Deque is however faster in this use than std::list or std::vector. + std::deque items; }; @@ -495,13 +500,15 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) } SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - std::list::iterator l = std::find(parent->items.begin(),parent->items.end(), item); + std::deque::iterator l = std::find(parent->items.begin(),parent->items.end(), item); g_assert (l != parent->items.end()); + std::deque::iterator l_orig = l; + for (int i=0; i<=positions && l != parent->items.end(); ++i) ++l; - parent->items.remove(item); + parent->items.erase(l_orig); parent->items.insert(l, item); redraw_if_visible (item); @@ -515,7 +522,8 @@ void sp_canvas_item_raise_to_top(SPCanvasItem *item) if (!item->parent) return; SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - parent->items.remove(item); + std::deque::iterator l = std::find(parent->items.begin(), parent->items.end(), item); + parent->items.erase(l); parent->items.push_back(item); redraw_if_visible (item); item->canvas->_need_repick = TRUE; @@ -544,13 +552,14 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) return; } - std::list::iterator l = std::find(parent->items.begin(), parent->items.end(), item); + std::deque::iterator l = std::find(parent->items.begin(), parent->items.end(), item); g_assert (l != parent->items.end()); + std::deque::iterator l_orig = l; for (int i=0; iitems.begin(); ++i) --l; - parent->items.remove(item); + parent->items.erase(l_orig); parent->items.insert(l, item); redraw_if_visible (item); @@ -564,7 +573,8 @@ void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) if (!item->parent) return; SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - parent->items.remove(item); + std::deque::iterator l = std::find(parent->items.begin(), parent->items.end(), item); + parent->items.erase(l); parent->items.push_front(item); redraw_if_visible (item); item->canvas->_need_repick = TRUE; @@ -768,7 +778,7 @@ gint sp_canvas_item_order (SPCanvasItem * item) { SPCanvasGroup * p = SP_CANVAS_GROUP(item->parent); size_t index = 0; - for (std::list::const_iterator it = p->items.begin(); it != p->items.end(); ++it, ++index) { + for (std::deque::const_iterator it = p->items.begin(); it != p->items.end(); ++it, ++index) { if ((*it) == item) { return index; } @@ -793,7 +803,7 @@ static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) static void sp_canvas_group_init(SPCanvasGroup * group) { - new (&group->items) std::list; + new (&group->items) std::deque; } void SPCanvasGroup::destroy(SPCanvasItem *object) @@ -803,12 +813,12 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) SPCanvasGroup *group = SP_CANVAS_GROUP(object); - for (std::list::iterator it = group->items.begin(); it != group->items.end(); ++it) { + for (std::deque::iterator it = group->items.begin(); it != group->items.end(); ++it) { sp_canvas_item_destroy(*it); } group->items.clear(); - group->items.~list(); // invoke manually + group->items.~deque(); // invoke manually if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); @@ -820,7 +830,7 @@ void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsig SPCanvasGroup const *group = SP_CANVAS_GROUP(item); Geom::OptRect bounds; - for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + for (std::deque::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *i = *it; sp_canvas_item_invoke_update (i, affine, flags); @@ -856,7 +866,7 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac *actual_item = nullptr; double dist = 0.0; - for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + for (std::deque::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) { @@ -890,7 +900,7 @@ void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf) { SPCanvasGroup const *group = SP_CANVAS_GROUP(item); - for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + for (std::deque::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if (child->visible) { if ((child->x1 < buf->rect.right()) && @@ -909,7 +919,7 @@ void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_ { SPCanvasGroup *group = SP_CANVAS_GROUP(item); - for (std::list::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + for (std::deque::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { SPCanvasItem *child = *it; if (child->visible) { if (SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed) {