From 109ec952f041590ee5f42ac6e7d6bd5c212c9441 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 18 Feb 2016 00:38:22 +0100 Subject: Fixes some regressions from rev14655 Fixed bugs: - https://launchpad.net/bugs/1546531 (bzr r14658) --- src/document.cpp | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'src/document.cpp') diff --git a/src/document.cpp b/src/document.cpp index 621cb071e..ae03b1ba1 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1335,34 +1335,24 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro /** Turn the SVG DOM into a flat list of nodes that can be searched from top-down. The list can be persisted, which improves "find at multiple points" speed. -Returns true if upto is reached. */ -bool SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups, bool take_insensitive, SPItem *upto) +void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const { - bool found_upto = false; for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { if (!SP_IS_ITEM(o)) { continue; } - if (upto && SP_ITEM(o) == upto) { - found_upto = true; - break; - } - if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - found_upto = build_flat_item_list(dkey, SP_GROUP(o), into_groups, take_insensitive, upto); - if (found_upto) - break; + build_flat_item_list(dkey, SP_GROUP(o), into_groups); } else { SPItem *child = SP_ITEM(o); - if (take_insensitive || child->isVisibleAndUnlocked(dkey)) { + if (child->isVisibleAndUnlocked(dkey)) { _node_cache.push_front(child); } } } - return found_upto; } /** @@ -1374,15 +1364,21 @@ upwards in z-order and returns what it has found so far (i.e. the found item is guaranteed to be lower than upto). Requires a list of nodes built by build_flat_item_list. */ -static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, Geom::Point const &p) +static SPItem *find_item_at_point(std::deque *nodes, unsigned int dkey, Geom::Point const &p, SPItem* upto=NULL) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); SPItem *seen = NULL; SPItem *child; + bool seen_upto = (!upto); for (std::deque::const_iterator i = nodes->begin(); i != nodes->end(); ++i) { child = *i; + if (!seen_upto){ + if(child == upto) + seen_upto = true; + continue; + } Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) { @@ -1454,7 +1450,7 @@ std::vector SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom: return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, false, into_groups); } -std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) +std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vector points, bool all_layers, size_t limit) const { std::vector items; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1468,7 +1464,7 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto // Cache a flattened SVG DOM to speed up selection. if(!_node_cache_valid){ _node_cache.clear(); - build_flat_item_list(key, SP_GROUP(this->root), true, false, NULL); + build_flat_item_list(key, SP_GROUP(this->root), true); _node_cache_valid=true; } SPObject *current_layer = SP_ACTIVE_DESKTOP->currentLayer(); @@ -1499,18 +1495,26 @@ std::vector SPDocument::getItemsAtPoints(unsigned const key, std::vecto } SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p, - bool const into_groups, SPItem *upto) + bool const into_groups, SPItem *upto) const { g_return_val_if_fail(this->priv != NULL, NULL); // Build a flattened SVG DOM for find_item_at_point. - if(!_node_cache_valid){ + std::deque bak(_node_cache); + if(!into_groups){ _node_cache.clear(); - build_flat_item_list(key, SP_GROUP(this->root), into_groups, false, upto); - if(!upto) - _node_cache_valid = true; + build_flat_item_list(key, SP_GROUP(this->root), into_groups); } - return find_item_at_point(&_node_cache, key, p); + if(!_node_cache_valid && into_groups){ + _node_cache.clear(); + build_flat_item_list(key, SP_GROUP(this->root), true); + _node_cache_valid=true; + } + + SPItem *res = find_item_at_point(&_node_cache, key, p, upto); + if(!into_groups) + _node_cache = bak; + return res; } SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const -- cgit v1.2.3