summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Valavanis <valavanisalex@gmail.com>2019-01-01 15:50:45 +0000
committerAlexander Valavanis <valavanisalex@gmail.com>2019-01-01 15:50:45 +0000
commitf1d64ae4334968100cb24b4bc17c4fd0e6a9729c (patch)
treee326b23234d6f6041628fd81f9a2b0316da90eb6 /src
parentMove Preview to Inkscape namespace (diff)
parentMerge remote-tracking branch 'origin/attribute-lookup-map' (diff)
downloadinkscape-f1d64ae4334968100cb24b4bc17c4fd0e6a9729c.tar.gz
inkscape-f1d64ae4334968100cb24b4bc17c4fd0e6a9729c.zip
Merge branch 'master' of gitlab.com:inkscape/inkscape
Diffstat (limited to 'src')
-rw-r--r--src/attributes.cpp34
-rw-r--r--src/attributes.h7
-rw-r--r--src/display/sp-canvas-item.h10
-rw-r--r--src/display/sp-canvas.cpp83
-rw-r--r--src/style.cpp15
5 files changed, 93 insertions, 56 deletions
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 1222d2669..d7081d4c9 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -9,6 +9,9 @@
* Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
+#include <cstring>
+#include <map>
+
#include <glib.h> // g_assert()
#include "attributes.h"
@@ -555,15 +558,34 @@ static SPStyleProp const props[] = {
#define n_attrs (sizeof(props) / sizeof(props[0]))
-/** Returns an SPAttributeEnum; SP_ATTR_INVALID (of value 0) if key isn't recognized. */
+/**
+ * Inverse to the \c props array for lookup by name.
+ */
+struct AttributeLookupImpl {
+ struct cstrless {
+ bool operator()(char const *lhs, char const *rhs) const { return std::strcmp(lhs, rhs) < 0; }
+ };
+
+ std::map<char const *, SPAttributeEnum, cstrless> m_map;
+
+ AttributeLookupImpl()
+ {
+ for (unsigned int i = 1; i < n_attrs; i++) {
+ // sanity check: order of props array must match SPAttributeEnum
+ g_assert(props[i].code == i);
+
+ m_map[props[i].name] = props[i].code;
+ }
+ }
+};
+
SPAttributeEnum
sp_attribute_lookup(gchar const *key)
{
- for (unsigned int i = 1; i < n_attrs; i++) {
- g_assert(props[i].code == static_cast< gint >(i) );
- // If this g_assert fails, then the sort order of SPAttributeEnum does not match the order in props[]!
- if(g_str_equal(const_cast<void *>(static_cast<void const *>(props[i].name)), key))
- return props[i].code;
+ static AttributeLookupImpl const _instance;
+ auto it = _instance.m_map.find(key);
+ if (it != _instance.m_map.end()) {
+ return it->second;
}
// std::cerr << "sp_attribute_lookup: invalid attribute: "
// << (key?key:"Null") << std::endl;
diff --git a/src/attributes.h b/src/attributes.h
index 1f0178fae..512c00499 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -564,7 +564,14 @@ enum SPAttributeEnum : unsigned {
SP_PROP_PATH_EFFECT,
};
+/**
+ * Get attribute id by name. Return SP_ATTR_INVALID for invalid names.
+ */
SPAttributeEnum sp_attribute_lookup(gchar const *key);
+
+/**
+ * Get attribute name by id. Return NULL for invalid ids.
+ */
gchar const *sp_attribute_name(SPAttributeEnum id);
#endif
diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h
index 65bd1cc05..fc6417325 100644
--- a/src/display/sp-canvas-item.h
+++ b/src/display/sp-canvas-item.h
@@ -21,6 +21,7 @@
*/
#include <2geom/rect.h>
+#include <boost/intrusive/list.hpp>
#include <glib-object.h>
#include "ui/control-types.h"
@@ -49,6 +50,9 @@ typedef struct _GdkCursor GdkCursor;
struct SPCanvasItem {
GInitiallyUnowned parent_instance;
+ // boost linked list member hook
+ boost::intrusive::list_member_hook<> member_hook_;
+
SPCanvas *canvas;
SPCanvasItem *parent;
@@ -78,6 +82,12 @@ struct SPCanvasItem {
GType sp_canvas_item_get_type();
+//Define type for linked list storing SPCanvasItems
+typedef boost::intrusive::list<
+ SPCanvasItem,
+ boost::intrusive::member_hook<SPCanvasItem, boost::intrusive::list_member_hook<>, &SPCanvasItem::member_hook_> >
+ SPCanvasItemList;
+
/**
* The vtable of an SPCanvasItem.
*/
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index 16f04d1f4..331528654 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -136,8 +136,7 @@ struct SPCanvasGroup {
SPCanvasItem item;
- std::list<SPCanvasItem *> items;
-
+ SPCanvasItemList items;
};
/**
@@ -272,6 +271,9 @@ void sp_canvas_item_construct(SPCanvasItem *item, SPCanvasGroup *parent, gchar c
g_return_if_fail(SP_IS_CANVAS_GROUP(parent));
g_return_if_fail(SP_IS_CANVAS_ITEM(item));
+ // manually invoke list_member_hook constructor
+ new (&(item->member_hook_)) boost::intrusive::list_member_hook<>();
+
item->parent = SP_CANVAS_ITEM(parent);
item->canvas = item->parent->canvas;
@@ -495,14 +497,15 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions)
}
SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent);
- std::list<SPCanvasItem *>::iterator l = std::find(parent->items.begin(),parent->items.end(), item);
- g_assert (l != parent->items.end());
+ auto from = parent->items.iterator_to(*item);
+ auto to = from;
- for (int i=0; i<=positions && l != parent->items.end(); ++i)
- ++l;
+ for (int i = 0; i <= positions && to != parent->items.end(); ++i) {
+ ++to;
+ }
- parent->items.remove(item);
- parent->items.insert(l, item);
+ parent->items.erase(from);
+ parent->items.insert(to, *item);
redraw_if_visible (item);
item->canvas->_need_repick = TRUE;
@@ -515,8 +518,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);
- parent->items.push_back(item);
+ parent->items.erase(parent->items.iterator_to(*item));
+ parent->items.push_back(*item);
redraw_if_visible (item);
item->canvas->_need_repick = TRUE;
}
@@ -540,18 +543,20 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions)
SPCanvasGroup *parent = SP_CANVAS_GROUP(item->parent);
- if (!parent || positions == 0 || item == parent->items.front() ) {
+ if (!parent || positions == 0 || item == &parent->items.front()) {
return;
}
- std::list<SPCanvasItem *>::iterator l = std::find(parent->items.begin(), parent->items.end(), item);
- g_assert (l != parent->items.end());
+ auto from = parent->items.iterator_to(*item);
+ auto to = from;
+ g_assert(from != parent->items.end());
- for (int i=0; i<positions && l != parent->items.begin(); ++i)
- --l;
+ for (int i = 0; i < positions && to != parent->items.begin(); ++i) {
+ --to;
+ }
- parent->items.remove(item);
- parent->items.insert(l, item);
+ parent->items.erase(from);
+ parent->items.insert(to, *item);
redraw_if_visible (item);
item->canvas->_need_repick = TRUE;
@@ -564,8 +569,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);
- parent->items.push_front(item);
+ parent->items.erase(parent->items.iterator_to(*item));
+ parent->items.push_front(*item);
redraw_if_visible (item);
item->canvas->_need_repick = TRUE;
}
@@ -768,8 +773,8 @@ gint sp_canvas_item_order (SPCanvasItem * item)
{
SPCanvasGroup * p = SP_CANVAS_GROUP(item->parent);
size_t index = 0;
- for (std::list<SPCanvasItem*>::const_iterator it = p->items.begin(); it != p->items.end(); ++it, ++index) {
- if ((*it) == item) {
+ for (auto it = p->items.begin(); it != p->items.end(); ++it, ++index) {
+ if (item == &(*it)) {
return index;
}
}
@@ -793,7 +798,7 @@ static void sp_canvas_group_class_init(SPCanvasGroupClass *klass)
static void sp_canvas_group_init(SPCanvasGroup * group)
{
- new (&group->items) std::list<SPCanvasItem *>;
+ new (&group->items) SPCanvasItemList;
}
void SPCanvasGroup::destroy(SPCanvasItem *object)
@@ -803,12 +808,14 @@ void SPCanvasGroup::destroy(SPCanvasItem *object)
SPCanvasGroup *group = SP_CANVAS_GROUP(object);
- for (std::list<SPCanvasItem *>::iterator it = group->items.begin(); it != group->items.end(); ++it) {
- sp_canvas_item_destroy(*it);
+ for (auto it = group->items.begin(); it != group->items.end();) {
+ SPCanvasItem *item = &(*it);
+ it++;
+ sp_canvas_item_destroy(item);
}
group->items.clear();
- group->items.~list(); // invoke manually
+ group->items.~SPCanvasItemList(); // invoke manually
if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) {
(* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object);
@@ -817,11 +824,11 @@ void SPCanvasGroup::destroy(SPCanvasItem *object)
void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags)
{
- SPCanvasGroup const *group = SP_CANVAS_GROUP(item);
+ SPCanvasGroup *group = SP_CANVAS_GROUP(item);
Geom::OptRect bounds;
- for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) {
- SPCanvasItem *i = *it;
+ for (auto it = group->items.begin(); it != group->items.end(); ++it) {
+ SPCanvasItem *i = &(*it);
sp_canvas_item_invoke_update (i, affine, flags);
@@ -844,7 +851,7 @@ void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsig
double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item)
{
- SPCanvasGroup const *group = SP_CANVAS_GROUP(item);
+ SPCanvasGroup *group = SP_CANVAS_GROUP(item);
double const x = p[Geom::X];
double const y = p[Geom::Y];
int x1 = (int)(x - item->canvas->_close_enough);
@@ -856,8 +863,8 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac
*actual_item = nullptr;
double dist = 0.0;
- for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) {
- SPCanvasItem *child = *it;
+ for (auto 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)) {
SPCanvasItem *point_item = nullptr; // cater for incomplete item implementations
@@ -888,10 +895,10 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac
void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf)
{
- SPCanvasGroup const *group = SP_CANVAS_GROUP(item);
+ SPCanvasGroup *group = SP_CANVAS_GROUP(item);
- for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) {
- SPCanvasItem *child = *it;
+ for (auto it = group->items.begin(); it != group->items.end(); ++it) {
+ SPCanvasItem *child = &(*it);
if (child->visible) {
if ((child->x1 < buf->rect.right()) &&
(child->y1 < buf->rect.bottom()) &&
@@ -909,8 +916,8 @@ void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_
{
SPCanvasGroup *group = SP_CANVAS_GROUP(item);
- for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) {
- SPCanvasItem *child = *it;
+ for (auto it = group->items.begin(); it != group->items.end(); ++it) {
+ SPCanvasItem *child = &(*it);
if (child->visible) {
if (SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed) {
SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed(child, new_area);
@@ -924,7 +931,7 @@ void SPCanvasGroup::add(SPCanvasItem *item)
g_object_ref(item);
g_object_ref_sink(item);
- items.push_back(item);
+ items.push_back(*item);
sp_canvas_item_request_update(item);
}
@@ -933,7 +940,7 @@ void SPCanvasGroup::remove(SPCanvasItem *item)
{
g_return_if_fail(item != nullptr);
- auto position = std::find(items.begin(), items.end(), item);
+ auto position = items.iterator_to(*item);
if (position != items.end()) {
items.erase(position);
}
diff --git a/src/style.cpp b/src/style.cpp
index aab8f2695..b11a92749 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -76,7 +76,7 @@ static CRSelEng *sp_repr_sel_eng();
class SPStylePropHelper {
SPStylePropHelper() {
#define REGISTER_PROPERTY(id, member, name) \
- _register(reinterpret_cast<SPIBasePtr>(&SPStyle::member), id, name)
+ _register(reinterpret_cast<SPIBasePtr>(&SPStyle::member), id) /* name unused */
// SVG 2: Attributes promoted to properties
REGISTER_PROPERTY(SP_ATTR_D, d, "d");
@@ -215,11 +215,7 @@ public:
* Get property pointer by name
*/
SPIBase *get(SPStyle *style, const std::string &name) {
- auto it = m_name_map.find(name);
- if (it != m_name_map.end()) {
- return _get(style, it->second);
- }
- return nullptr;
+ return get(style, sp_attribute_lookup(name.c_str()));
}
/**
@@ -238,19 +234,14 @@ public:
private:
SPIBase *_get(SPStyle *style, SPIBasePtr ptr) { return &(style->*ptr); }
- void _register(SPIBasePtr ptr, SPAttributeEnum id, const char *name) {
+ void _register(SPIBasePtr ptr, SPAttributeEnum id) {
m_vector.push_back(ptr);
if (id != SP_ATTR_INVALID) {
m_id_map[id] = ptr;
}
-
- if (name[0]) {
- m_name_map[name] = ptr;
- }
}
- std::unordered_map<std::string, SPIBasePtr> m_name_map;
std::unordered_map</* SPAttributeEnum */ int, SPIBasePtr> m_id_map;
std::vector<SPIBasePtr> m_vector;
};