summaryrefslogtreecommitdiffstats
path: root/src/splivarot.cpp
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-07-24 19:53:33 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-07-24 19:53:33 +0000
commit5a37f06c70e0e4e2519812564f4dcdced7c0246a (patch)
treef959f73813cb6f968072aee1100323b24e294136 /src/splivarot.cpp
parentupdate to trunk (diff)
parentFix a bug continuing a bezier path whith a LPE one like spiro or bspline on a... (diff)
downloadinkscape-5a37f06c70e0e4e2519812564f4dcdced7c0246a.tar.gz
inkscape-5a37f06c70e0e4e2519812564f4dcdced7c0246a.zip
update to trunk
(bzr r13879.1.17)
Diffstat (limited to 'src/splivarot.cpp')
-rw-r--r--src/splivarot.cpp144
1 files changed, 73 insertions, 71 deletions
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index 46279cbce..726df6e20 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -47,6 +47,7 @@
#include "xml/repr.h"
#include "xml/repr-sorting.h"
#include <2geom/pathvector.h>
+#include <2geom/svg-path-writer.h>
#include "helper/geom.h"
#include "livarot/Path.h"
@@ -305,8 +306,9 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat
delete originaux[0];
delete originaux[1];
- std::vector<Geom::Path> outres = Geom::parse_svg_path(res->svg_dump_path());
-
+ gchar *result_str = res->svg_dump_path();
+ Geom::PathVector outres = Geom::parse_svg_path(result_str);
+ g_free(result_str);
delete res;
return outres;
@@ -315,7 +317,7 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat
/* Convert from a livarot path to a 2geom PathVector */
Geom::PathVector pathliv_to_pathvector(Path *pathliv){
- std::vector<Geom::Path> outres = Geom::parse_svg_path(pathliv->svg_dump_path());
+ Geom::PathVector outres = Geom::parse_svg_path(pathliv->svg_dump_path());
return outres;
}
@@ -326,21 +328,21 @@ void
sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description)
{
SPDocument *doc = selection->layers()->getDocument();
- GSList *il = (GSList *) selection->itemList();
+ std::vector<SPItem*> il= selection->itemList();
// allow union on a single object for the purpose of removing self overlapse (svn log, revision 13334)
- if ( (g_slist_length(il) < 2) && (bop != bool_op_union)) {
+ if ( (il.size() < 2) && (bop != bool_op_union)) {
boolop_display_error_message(desktop, _("Select <b>at least 2 paths</b> to perform a boolean operation."));
return;
}
- else if ( g_slist_length(il) < 1 ) {
+ else if ( il.size() < 1 ) {
boolop_display_error_message(desktop, _("Select <b>at least 1 path</b> to perform a boolean union."));
return;
}
- g_assert(il != NULL);
+ g_assert(!il.empty());
- if (g_slist_length(il) > 2) {
+ if (il.size() > 2) {
if (bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice ) {
boolop_display_error_message(desktop, _("Select <b>exactly 2 paths</b> to perform difference, division, or path cut."));
return;
@@ -354,8 +356,8 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
if (bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice) {
// check in the tree to find which element of the selection list is topmost (for 2-operand commands only)
- Inkscape::XML::Node *a = SP_OBJECT(il->data)->getRepr();
- Inkscape::XML::Node *b = SP_OBJECT(il->next->data)->getRepr();
+ Inkscape::XML::Node *a = il.front()->getRepr();
+ Inkscape::XML::Node *b = il.back()->getRepr();
if (a == NULL || b == NULL) {
boolop_display_error_message(desktop, _("Unable to determine the <b>z-order</b> of the objects selected for difference, XOR, division, or path cut."));
@@ -394,38 +396,36 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
}
}
- il = g_slist_copy(il);
- g_assert(il != NULL);
+ g_assert(!il.empty());
// first check if all the input objects have shapes
// otherwise bail out
- for (GSList *l = il; l != NULL; l = l->next)
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++)
{
- SPItem *item = SP_ITEM(l->data);
+ SPItem *item = *l;
if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item) && !SP_IS_FLOWTEXT(item))
{
boolop_display_error_message(desktop, _("One of the objects is <b>not a path</b>, cannot perform boolean operation."));
- g_slist_free(il);
return;
}
}
// extract the livarot Paths from the source objects
// also get the winding rule specified in the style
- int nbOriginaux = g_slist_length(il);
+ int nbOriginaux = il.size();
std::vector<Path *> originaux(nbOriginaux);
std::vector<FillRule> origWind(nbOriginaux);
int curOrig;
{
curOrig = 0;
- for (GSList *l = il; l != NULL; l = l->next)
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++)
{
// apply live path effects prior to performing boolean operation
- if (SP_IS_LPE_ITEM(l->data)) {
- SP_LPE_ITEM(l->data)->removeAllPathEffects(true);
+ if (SP_IS_LPE_ITEM(*l)) {
+ SP_LPE_ITEM(*l)->removeAllPathEffects(true);
}
- SPCSSAttr *css = sp_repr_css_attr(reinterpret_cast<SPObject *>(il->data)->getRepr(), "style");
+ SPCSSAttr *css = sp_repr_css_attr(reinterpret_cast<SPObject *>(il[0])->getRepr(), "style");
gchar const *val = sp_repr_css_property(css, "fill-rule", NULL);
if (val && strcmp(val, "nonzero") == 0) {
origWind[curOrig]= fill_nonZero;
@@ -435,11 +435,10 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
origWind[curOrig]= fill_nonZero;
}
- originaux[curOrig] = Path_for_item((SPItem *) l->data, true, true);
+ originaux[curOrig] = Path_for_item(*l, true, true);
if (originaux[curOrig] == NULL || originaux[curOrig]->descr_cmd.size() <= 1)
{
for (int i = curOrig; i >= 0; i--) delete originaux[i];
- g_slist_free(il);
return;
}
curOrig++;
@@ -448,8 +447,9 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
// reverse if needed
// note that the selection list keeps its order
if ( reverseOrderForOp ) {
- Path* swap=originaux[0];originaux[0]=originaux[1];originaux[1]=swap;
- FillRule swai=origWind[0]; origWind[0]=origWind[1]; origWind[1]=swai;
+ using std::swap;
+ swap(originaux[0], originaux[1]);
+ swap(origWind[0], origWind[1]);
}
// and work
@@ -472,7 +472,8 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
theShapeA->ConvertToShape(theShape, origWind[0]);
curOrig = 1;
- for (GSList *l = il->next; l != NULL; l = l->next) {
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
+ if(*l==il[0])continue;
originaux[curOrig]->ConvertWithBackData(0.1);
originaux[curOrig]->Fill(theShape, curOrig);
@@ -668,15 +669,13 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
if (res->descr_cmd.size() <= 1)
{
// only one command, presumably a moveto: it isn't a path
- for (GSList *l = il; l != NULL; l = l->next)
- {
- SP_OBJECT(l->data)->deleteObject();
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
+ (*l)->deleteObject();
}
DocumentUndo::done(doc, SP_VERB_NONE, description);
selection->clear();
delete res;
- g_slist_free(il);
return;
}
@@ -684,19 +683,17 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
SPObject *source;
if ( bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice ) {
if (reverseOrderForOp) {
- source = SP_OBJECT(il->data);
+ source = il[0];
} else {
- source = SP_OBJECT(il->next->data);
+ source = il.back();
}
} else {
// find out the bottom object
- GSList *sorted = g_slist_copy((GSList *) selection->reprList());
+ std::vector<Inkscape::XML::Node*> sorted(selection->reprList());
- sorted = g_slist_sort(sorted, (GCompareFunc) sp_repr_compare_position);
+ sort(sorted.begin(),sorted.end(),sp_repr_compare_position_bool);
- source = doc->getObjectByRepr((Inkscape::XML::Node *)sorted->data);
-
- g_slist_free(sorted);
+ source = doc->getObjectByRepr(sorted.front());
}
// adjust style properties that depend on a possible transform in the source object in order
@@ -721,17 +718,16 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool
gchar *desc = source->desc();
// remove source paths
selection->clear();
- for (GSList *l = il; l != NULL; l = l->next) {
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
// if this is the bottommost object,
- if (!strcmp(reinterpret_cast<SPObject *>(l->data)->getRepr()->attribute("id"), id)) {
+ if (!strcmp(reinterpret_cast<SPObject *>(*l)->getRepr()->attribute("id"), id)) {
// delete it so that its clones don't get alerted; this object will be restored shortly, with the same id
- SP_OBJECT(l->data)->deleteObject(false);
+ (*l)->deleteObject(false);
} else {
// delete the object for real, so that its clones can take appropriate action
- SP_OBJECT(l->data)->deleteObject();
+ (*l)->deleteObject();
}
}
- g_slist_free(il);
// premultiply by the inverse of parent's repr
SPItem *parent_item = SP_ITEM(doc->getObjectByRepr(parent));
@@ -1159,12 +1155,9 @@ sp_selected_path_outline(SPDesktop *desktop)
}
bool did = false;
-
- for (GSList *items = g_slist_copy((GSList *) selection->itemList());
- items != NULL;
- items = items->next) {
-
- SPItem *item = SP_ITEM(items->data);
+ std::vector<SPItem*> il(selection->itemList());
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
+ SPItem *item = *l;
if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item))
continue;
@@ -1776,12 +1769,9 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset)
}
bool did = false;
-
- for (GSList *items = g_slist_copy((GSList *) selection->itemList());
- items != NULL;
- items = items->next) {
-
- SPItem *item = SP_ITEM(items->data);
+ std::vector<SPItem*> il(selection->itemList());
+ for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){
+ SPItem *item = *l;
SPCurve *curve = NULL;
if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item))
@@ -1977,7 +1967,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset)
static bool
sp_selected_path_simplify_items(SPDesktop *desktop,
- Inkscape::Selection *selection, GSList *items,
+ Inkscape::Selection *selection, std::vector<SPItem*> &items,
float threshold, bool justCoalesce,
float angleLimit, bool breakableAngles,
bool modifySelection);
@@ -1996,7 +1986,7 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
//If this is a group, do the children instead
if (SP_IS_GROUP(item)) {
- GSList *items = sp_item_group_item_list(SP_GROUP(item));
+ std::vector<SPItem*> items = sp_item_group_item_list(SP_GROUP(item));
return sp_selected_path_simplify_items(desktop, selection, items,
threshold, justCoalesce,
@@ -2121,7 +2111,7 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
bool
sp_selected_path_simplify_items(SPDesktop *desktop,
- Inkscape::Selection *selection, GSList *items,
+ Inkscape::Selection *selection, std::vector<SPItem*> &items,
float threshold, bool justCoalesce,
float angleLimit, bool breakableAngles,
bool modifySelection)
@@ -2147,13 +2137,13 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
gdouble simplifySize = selectionSize;
int pathsSimplified = 0;
- int totalPathCount = g_slist_length(items);
+ int totalPathCount = items.size();
// set "busy" cursor
desktop->setWaitingCursor();
- for (; items != NULL; items = items->next) {
- SPItem *item = (SPItem *) items->data;
+ for (std::vector<SPItem*>::const_iterator l = items.begin(); l != items.end(); l++){
+ SPItem *item = *l;
if (!(SP_IS_GROUP(item) || SP_IS_SHAPE(item) || SP_IS_TEXT(item)))
continue;
@@ -2201,7 +2191,7 @@ sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool ju
return;
}
- GSList *items = g_slist_copy((GSList *) selection->itemList());
+ std::vector<SPItem*> items(selection->itemList());
bool didSomething = sp_selected_path_simplify_items(desktop, selection,
items, threshold,
@@ -2273,17 +2263,17 @@ Ancetre(Inkscape::XML::Node *a, Inkscape::XML::Node *who)
}
// derived from Path_for_item
-// there must be some other way to load dest directly from epathv, without going through pathv...
Path *
Path_for_pathvector(Geom::PathVector const &epathv)
{
- Geom::PathVector *pathv = new Geom::PathVector;
- std::copy(epathv.begin(), epathv.end(), std::back_inserter(*pathv));
-
+ /*std::cout << "converting to Livarot path" << std::endl;
+
+ Geom::SVGPathWriter wr;
+ wr.feed(epathv);
+ std::cout << wr.str() << std::endl;*/
+
Path *dest = new Path;
- dest->LoadPathVector(*pathv);
- delete pathv;
-
+ dest->LoadPathVector(epathv);
return dest;
}
@@ -2294,14 +2284,26 @@ Path_for_item(SPItem *item, bool doTransformation, bool transformFull)
if (curve == NULL)
return NULL;
-
+
Geom::PathVector *pathv = pathvector_for_curve(item, curve, doTransformation, transformFull, Geom::identity(), Geom::identity());
curve->unref();
-
+
+ /*std::cout << "converting to Livarot path" << std::endl;
+
+ Geom::SVGPathWriter wr;
+ if (pathv) {
+ wr.feed(*pathv);
+ }
+ std::cout << wr.str() << std::endl;*/
+
Path *dest = new Path;
dest->LoadPathVector(*pathv);
delete pathv;
-
+
+ /*gchar *str = dest->svg_dump_path();
+ std::cout << "After conversion:\n" << str << std::endl;
+ g_free(str);*/
+
return dest;
}
@@ -2348,7 +2350,7 @@ pathvector_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool t
} else {
*dest *= extraPreAffine * extraPostAffine;
}
-
+
return dest;
}