summaryrefslogtreecommitdiffstats
path: root/src/selection-chemistry.cpp
diff options
context:
space:
mode:
authorTomasz Boczkowski <penginsbacon@gmail.com>2015-05-09 11:38:22 +0000
committerTomasz Boczkowski <penginsbacon@gmail.com>2015-05-09 11:38:22 +0000
commitdb85d12f8c106586a0b11f60bf32cdb8ca75d8f2 (patch)
treeae5cbc2ad4fdbb93dbc1d7fc8b92ee2e2012e853 /src/selection-chemistry.cpp
parentrenamed SPPattern methods to match coding style (diff)
parentfix crash introduces by recent rev when clipping (diff)
downloadinkscape-db85d12f8c106586a0b11f60bf32cdb8ca75d8f2.tar.gz
inkscape-db85d12f8c106586a0b11f60bf32cdb8ca75d8f2.zip
merged trunk
(bzr r14059.1.21)
Diffstat (limited to 'src/selection-chemistry.cpp')
-rw-r--r--src/selection-chemistry.cpp150
1 files changed, 65 insertions, 85 deletions
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index a604064cc..971c8dcee 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -927,7 +927,7 @@ static SPObject *prev_sibling(SPObject *child)
return prev;
}
-int sp_item_repr_compare_position_obj(SPObject const *first, SPObject const *second)
+bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *second)
{
return sp_repr_compare_position(((SPItem*)first)->getRepr(),
((SPItem*)second)->getRepr())<0;
@@ -952,7 +952,7 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop)
/* Construct reverse-ordered list of selected children. */
std::vector<SPItem*> rev(items);
- sort(rev.begin(),rev.end(),sp_item_repr_compare_position);
+ sort(rev.begin(),rev.end(),sp_item_repr_compare_position_bool);
// Determine the common bbox of the selected items.
Geom::OptRect selected = enclose_items(items);
@@ -1034,7 +1034,7 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop)
/* Construct direct-ordered list of selected children. */
std::vector<SPItem*> rev(items);
- sort(rev.begin(),rev.end(),sp_item_repr_compare_position);
+ sort(rev.begin(),rev.end(),sp_item_repr_compare_position_bool);
// Iterate over all objects in the selection (starting from top).
if (selected) {
@@ -1837,6 +1837,15 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea
Inkscape::Selection *selection = desktop->getSelection();
std::vector<SPItem*> items = selection->itemList();
+
+ std::vector<SPItem*> tmp;
+ for (std::vector<SPItem*>::const_iterator iter=all_list.begin();iter!=all_list.end();iter++) {
+ if(!SP_IS_GROUP(*iter)){
+ tmp.push_back(*iter);
+ }
+ }
+ all_list=tmp;
+
for (std::vector<SPItem*>::const_iterator sel_iter=items.begin();sel_iter!=items.end();sel_iter++) {
SPItem *sel = *sel_iter;
std::vector<SPItem*> matches = all_list;
@@ -3509,7 +3518,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
std::vector<SPItem*> items(selection->itemList());
// Sort items so that the topmost comes last
- sort(items.begin(),items.end(),sp_item_repr_compare_position);
+ sort(items.begin(),items.end(),sp_item_repr_compare_position_bool);
// Generate a random value from the current time (you may create bitmap from the same object(s)
// multiple times, and this is done so that they don't clash)
@@ -3778,13 +3787,11 @@ void sp_selection_set_clipgroup(SPDesktop *desktop)
clone->setAttribute("inkscape:transform-center-y", inner->attribute("inkscape:transform-center-y"), false);
const Geom::Affine maskTransform(Geom::Affine::identity());
- GSList *templist = NULL;
-
- templist = g_slist_append(templist, clone);
+ std::vector<Inkscape::XML::Node*> templist;
+ templist.push_back(clone);
// add the new clone to the top of the original's parent
gchar const *mask_id = SPClipPath::create(templist, doc, &maskTransform);
- g_slist_free(templist);
outer->setAttribute("clip-path", g_strdup_printf("url(#%s)", mask_id));
@@ -3842,9 +3849,9 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
selection->clear();
// create a list of duplicates
- GSList *mask_items = NULL;
- GSList *apply_to_items = NULL;
- GSList *items_to_delete = NULL;
+ std::vector<Inkscape::XML::Node*> mask_items;
+ std::vector<SPItem*> apply_to_items;
+ std::vector<SPItem*> items_to_delete;
std::vector<SPItem*> items_to_select;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -3854,54 +3861,36 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
if (apply_to_layer) {
// all selected items are used for mask, which is applied to a layer
- apply_to_items = g_slist_prepend(apply_to_items, desktop->currentLayer());
+ apply_to_items.push_back(SP_ITEM(desktop->currentLayer()));
+ }
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ if((!topmost && !apply_to_layer && *i == items.front())
+ || (topmost && !apply_to_layer && *i == items.back())
+ || apply_to_layer){
+
+ Geom::Affine oldtr=(*i)->transform;
+ (*i)->doWriteTransform((*i)->getRepr(), (*i)->i2doc_affine());
Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
+ (*i)->doWriteTransform((*i)->getRepr(), oldtr);
+ mask_items.push_back(dup);
- SPObject *item = *i;
if (remove_original) {
- items_to_delete = g_slist_prepend(items_to_delete, item);
+ items_to_delete.push_back(*i);
}
else {
- items_to_select.push_back((SPItem*)item);
+ items_to_select.push_back(*i);
}
- }
- } else if (!topmost) {
- // topmost item is used as a mask, which is applied to other items in a selection
- Inkscape::XML::Node *dup = items[0]->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
-
- if (remove_original) {
- SPObject *item = items.front();
- items_to_delete = g_slist_prepend(items_to_delete, item);
- }
-
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
- if(i==items.begin())continue;
- apply_to_items = g_slist_prepend(apply_to_items, *i);
+ continue;
+ }else{
+ apply_to_items.push_back(*i);
items_to_select.push_back(*i);
}
- } else {
- SPItem *i = NULL;
- for (std::vector<SPItem*>::const_iterator j=items.begin();j!=items.end();j++) {
- i=*j;
- apply_to_items = g_slist_prepend(apply_to_items, i);
- items_to_select.push_back(i);
- }
-
- Inkscape::XML::Node *dup = SP_OBJECT(i)->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
-
- if (remove_original) {
- SPObject *item = reinterpret_cast<SPObject*>(i);
- items_to_delete = g_slist_prepend(items_to_delete, item);
- }
}
+
items.clear();
- if (apply_to_items && grouping == PREFS_MASKOBJECT_GROUPING_ALL) {
+ if (grouping == PREFS_MASKOBJECT_GROUPING_ALL) {
// group all those objects into one group
// and apply mask to that
Inkscape::XML::Node *group = xml_doc->createElement("svg:g");
@@ -3910,48 +3899,35 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
group->setAttribute("inkscape:groupmode", "maskhelper");
std::vector<Inkscape::XML::Node*> reprs_to_group;
-
- for (GSList *i = apply_to_items ; NULL != i ; i = i->next) {
- reprs_to_group.push_back(static_cast<SPObject*>(i->data)->getRepr());
- items_to_select.erase(find(items_to_select.begin(),items_to_select.end(),static_cast<SPObject*>(i->data)));
+ for (std::vector<SPItem*>::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); i++) {
+ reprs_to_group.push_back(static_cast<SPObject*>(*i)->getRepr());
}
+ items_to_select.clear();
sp_selection_group_impl(reprs_to_group, group, xml_doc, doc);
// apply clip/mask only to newly created group
- g_slist_free(apply_to_items);
- apply_to_items = NULL;
- apply_to_items = g_slist_prepend(apply_to_items, doc->getObjectByRepr(group));
+ apply_to_items.clear();
+ apply_to_items.push_back(dynamic_cast<SPItem*>(doc->getObjectByRepr(group)));
items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group)));
Inkscape::GC::release(group);
}
+ if (grouping == PREFS_MASKOBJECT_GROUPING_SEPARATE) {
+ items_to_select.clear();
+ }
+
gchar const *attributeName = apply_clip_path ? "clip-path" : "mask";
- for (GSList *i = apply_to_items; NULL != i; i = i->next) {
- SPItem *item = reinterpret_cast<SPItem *>(i->data);
+ for (std::vector<SPItem*>::const_reverse_iterator i = apply_to_items.rbegin(); i != apply_to_items.rend(); i++) {
+ SPItem *item = reinterpret_cast<SPItem *>(*i);
// inverted object transform should be applied to a mask object,
// as mask is calculated in user space (after applying transform)
- Geom::Affine maskTransform(item->transform.inverse());
-
- GSList *mask_items_dup = NULL;
- for (GSList *mask_item = mask_items; NULL != mask_item; mask_item = mask_item->next) {
- Inkscape::XML::Node *dup = reinterpret_cast<Inkscape::XML::Node *>(mask_item->data)->duplicate(xml_doc);
- mask_items_dup = g_slist_prepend(mask_items_dup, dup);
- }
-
- gchar const *mask_id = NULL;
- if (apply_clip_path) {
- mask_id = SPClipPath::create(mask_items_dup, doc, &maskTransform);
- } else {
- mask_id = sp_mask_create(mask_items_dup, doc, &maskTransform);
- }
-
- g_slist_free(mask_items_dup);
- mask_items_dup = NULL;
-
- Inkscape::XML::Node *current = SP_OBJECT(i->data)->getRepr();
+ std::vector<Inkscape::XML::Node*> mask_items_dup;
+ for(std::vector<Inkscape::XML::Node*>::const_iterator it=mask_items.begin();it!=mask_items.end();it++)
+ mask_items_dup.push_back((*it)->duplicate(xml_doc));
+ Inkscape::XML::Node *current = SP_OBJECT(*i)->getRepr();
// Node to apply mask to
Inkscape::XML::Node *apply_mask_to = current;
@@ -3963,7 +3939,6 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
Inkscape::XML::Node *spnew = current->duplicate(xml_doc);
gint position = current->position();
- items_to_select.erase(find(items_to_select.begin(),items_to_select.end(),item));
current->parent()->appendChild(group);
sp_repr_unparent(current);
group->appendChild(spnew);
@@ -3972,24 +3947,29 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
// Apply clip/mask to group instead
apply_mask_to = group;
- items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group)));
+ items_to_select.push_back(item = (SPItem*)(doc->getObjectByRepr(group)));
Inkscape::GC::release(spnew);
Inkscape::GC::release(group);
}
+ Geom::Affine maskTransform(item->i2doc_affine().inverse());
+
+ gchar const *mask_id = NULL;
+ if (apply_clip_path) {
+ mask_id = SPClipPath::create(mask_items_dup, doc, &maskTransform);
+ } else {
+ mask_id = sp_mask_create(mask_items_dup, doc, &maskTransform);
+ }
+
apply_mask_to->setAttribute(attributeName, Glib::ustring("url(#") + mask_id + ')');
}
- g_slist_free(mask_items);
- g_slist_free(apply_to_items);
-
- for (GSList *i = items_to_delete; NULL != i; i = i->next) {
- SPObject *item = reinterpret_cast<SPObject*>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = items_to_delete.begin(); i != items_to_delete.end(); i++) {
+ SPObject *item = reinterpret_cast<SPObject*>(*i);
item->deleteObject(false);
- items_to_select.erase(find(items_to_select.begin(),items_to_select.end(),item));
+ items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end());
}
- g_slist_free(items_to_delete);
selection->addList(items_to_select);
@@ -4112,7 +4092,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) {
for (GSList *i = items_to_ungroup ; NULL != i ; i = i->next) {
SPGroup *group = dynamic_cast<SPGroup *>(static_cast<SPObject *>(i->data));
if (group) {
- items_to_select.erase(find(items_to_select.begin(),items_to_select.end(),group));
+ items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), group), items_to_select.end());
std::vector<SPItem*> children;
sp_item_group_ungroup(group, children, false);
items_to_select.insert(items_to_select.end(),children.rbegin(),children.rend());