summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Moulder <peter.moulder@monash.edu>2008-03-29 09:49:50 +0000
committerpjrm <pjrm@users.sourceforge.net>2008-03-29 09:49:50 +0000
commit758276376139a9bb48b343c29463ba28563fab5b (patch)
tree4c7c4c0ccf49927e5f9b4120215933a6367ab7ac /src
parentnoop: Translate some comments. Use utf-8 for originals. (diff)
downloadinkscape-758276376139a9bb48b343c29463ba28563fab5b.tar.gz
inkscape-758276376139a9bb48b343c29463ba28563fab5b.zip
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**).
(bzr r5227)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/angle.h100
-rw-r--r--src/2geom/poly-dk-solve.cpp128
-rw-r--r--src/2geom/poly-laguerre-solve.cpp294
-rw-r--r--src/2geom/sweep.cpp210
-rw-r--r--src/libgdl/gdl-win32.c84
-rw-r--r--src/libgdl/gdl-win32.h60
-rw-r--r--src/live_effects/parameter/path-reference.cpp106
-rw-r--r--src/live_effects/parameter/path-reference.h120
-rw-r--r--src/live_effects/parameter/pointparam-knotholder.cpp402
-rw-r--r--src/sp-lpe-item.cpp902
-rw-r--r--src/sp-lpe-item.h138
11 files changed, 1272 insertions, 1272 deletions
diff --git a/src/2geom/angle.h b/src/2geom/angle.h
index 4d548ab49..79e12c954 100644
--- a/src/2geom/angle.h
+++ b/src/2geom/angle.h
@@ -1,50 +1,50 @@
-/**
- * \file angle.h
- * \brief Various trigoniometric helper functions
- *
- * Authors:
- * Johan Engelen <goejendaagh@zonnet.nl>
- *
- * Copyright (C) 2007 authors
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- */
-
-#ifndef LIB2GEOM_SEEN_ANGLE_H
-#define LIB2GEOM_SEEN_ANGLE_H
-
-namespace Geom {
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif
-
-inline double deg_to_rad(double deg) { return deg*M_PI/180.0;}
-
-inline double rad_to_deg(double rad) { return rad*180.0/M_PI;}
-
-}
-
-#endif
+/**
+ * \file angle.h
+ * \brief Various trigoniometric helper functions
+ *
+ * Authors:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
+#ifndef LIB2GEOM_SEEN_ANGLE_H
+#define LIB2GEOM_SEEN_ANGLE_H
+
+namespace Geom {
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+inline double deg_to_rad(double deg) { return deg*M_PI/180.0;}
+
+inline double rad_to_deg(double rad) { return rad*180.0/M_PI;}
+
+}
+
+#endif
diff --git a/src/2geom/poly-dk-solve.cpp b/src/2geom/poly-dk-solve.cpp
index 87d238f14..fdc1cefe5 100644
--- a/src/2geom/poly-dk-solve.cpp
+++ b/src/2geom/poly-dk-solve.cpp
@@ -1,64 +1,64 @@
-#include "poly-dk-solve.h"
-#include <iterator>
-
-/*** implementation of the Durand-Kerner method. seems buggy*/
-
-std::complex<double> evalu(Poly const & p, std::complex<double> x) {
- std::complex<double> result = 0;
- std::complex<double> xx = 1;
-
- for(unsigned i = 0; i < p.size(); i++) {
- result += p[i]*xx;
- xx *= x;
- }
- return result;
-}
-
-std::vector<std::complex<double> > DK(Poly const & ply, const double tol) {
- std::vector<std::complex<double> > roots;
- const int N = ply.degree();
-
- std::complex<double> b(0.4, 0.9);
- std::complex<double> p = 1;
- for(int i = 0; i < N; i++) {
- roots.push_back(p);
- p *= b;
- }
- assert(roots.size() == ply.degree());
-
- double error = 0;
- int i;
- for( i = 0; i < 30; i++) {
- error = 0;
- for(int r_i = 0; r_i < N; r_i++) {
- std::complex<double> denom = 1;
- std::complex<double> R = roots[r_i];
- for(int d_i = 0; d_i < N; d_i++) {
- if(r_i != d_i)
- denom *= R-roots[d_i];
- }
- assert(norm(denom) != 0);
- std::complex<double> dr = evalu(ply, R)/denom;
- error += norm(dr);
- roots[r_i] = R - dr;
- }
- /*std::copy(roots.begin(), roots.end(), std::ostream_iterator<std::complex<double> >(std::cout, ",\t"));
- std::cout << std::endl;*/
- if(error < tol)
- break;
- }
- //std::cout << error << ", " << i<< std::endl;
- return roots;
-}
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+#include "poly-dk-solve.h"
+#include <iterator>
+
+/*** implementation of the Durand-Kerner method. seems buggy*/
+
+std::complex<double> evalu(Poly const & p, std::complex<double> x) {
+ std::complex<double> result = 0;
+ std::complex<double> xx = 1;
+
+ for(unsigned i = 0; i < p.size(); i++) {
+ result += p[i]*xx;
+ xx *= x;
+ }
+ return result;
+}
+
+std::vector<std::complex<double> > DK(Poly const & ply, const double tol) {
+ std::vector<std::complex<double> > roots;
+ const int N = ply.degree();
+
+ std::complex<double> b(0.4, 0.9);
+ std::complex<double> p = 1;
+ for(int i = 0; i < N; i++) {
+ roots.push_back(p);
+ p *= b;
+ }
+ assert(roots.size() == ply.degree());
+
+ double error = 0;
+ int i;
+ for( i = 0; i < 30; i++) {
+ error = 0;
+ for(int r_i = 0; r_i < N; r_i++) {
+ std::complex<double> denom = 1;
+ std::complex<double> R = roots[r_i];
+ for(int d_i = 0; d_i < N; d_i++) {
+ if(r_i != d_i)
+ denom *= R-roots[d_i];
+ }
+ assert(norm(denom) != 0);
+ std::complex<double> dr = evalu(ply, R)/denom;
+ error += norm(dr);
+ roots[r_i] = R - dr;
+ }
+ /*std::copy(roots.begin(), roots.end(), std::ostream_iterator<std::complex<double> >(std::cout, ",\t"));
+ std::cout << std::endl;*/
+ if(error < tol)
+ break;
+ }
+ //std::cout << error << ", " << i<< std::endl;
+ return roots;
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/2geom/poly-laguerre-solve.cpp b/src/2geom/poly-laguerre-solve.cpp
index 921ec3e3b..766f16eda 100644
--- a/src/2geom/poly-laguerre-solve.cpp
+++ b/src/2geom/poly-laguerre-solve.cpp
@@ -1,147 +1,147 @@
-#include "poly-laguerre-solve.h"
-#include <iterator>
-
-typedef std::complex<double> cdouble;
-
-cdouble laguerre_internal_complex(Poly const & p,
- double x0,
- double tol,
- bool & quad_root) {
- cdouble a = 2*tol;
- cdouble xk = x0;
- double n = p.degree();
- quad_root = false;
- const unsigned shuffle_rate = 10;
- static double shuffle[] = {0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0};
- unsigned shuffle_counter = 0;
- while(std::norm(a) > (tol*tol)) {
- //std::cout << "xk = " << xk << std::endl;
- cdouble b = p.back();
- cdouble d = 0, f = 0;
- double err = abs(b);
- double abx = abs(xk);
- for(int j = p.size()-2; j >= 0; j--) {
- f = xk*f + d;
- d = xk*d + b;
- b = xk*b + p[j];
- err = abs(b) + abx*err;
- }
-
- err *= 1e-7; // magic epsilon for convergence, should be computed from tol
-
- cdouble px = b;
- if(abs(b) < err)
- return xk;
- //if(std::norm(px) < tol*tol)
- // return xk;
- cdouble G = d / px;
- cdouble H = G*G - f / px;
-
- //std::cout << "G = " << G << "H = " << H;
- cdouble radicand = (n - 1)*(n*H-G*G);
- //assert(radicand.real() > 0);
- if(radicand.real() < 0)
- quad_root = true;
- //std::cout << "radicand = " << radicand << std::endl;
- if(G.real() < 0) // here we try to maximise the denominator avoiding cancellation
- a = - sqrt(radicand);
- else
- a = sqrt(radicand);
- //std::cout << "a = " << a << std::endl;
- a = n / (a + G);
- //std::cout << "a = " << a << std::endl;
- if(shuffle_counter % shuffle_rate == 0)
- ;//a *= shuffle[shuffle_counter / shuffle_rate];
- xk -= a;
- shuffle_counter++;
- if(shuffle_counter >= 90)
- break;
- }
- //std::cout << "xk = " << xk << std::endl;
- return xk;
-}
-
-double laguerre_internal(Poly const & p,
- Poly const & pp,
- Poly const & ppp,
- double x0,
- double tol,
- bool & quad_root) {
- double a = 2*tol;
- double xk = x0;
- double n = p.degree();
- quad_root = false;
- while(a*a > (tol*tol)) {
- //std::cout << "xk = " << xk << std::endl;
- double px = p(xk);
- if(px*px < tol*tol)
- return xk;
- double G = pp(xk) / px;
- double H = G*G - ppp(xk) / px;
-
- //std::cout << "G = " << G << "H = " << H;
- double radicand = (n - 1)*(n*H-G*G);
- assert(radicand > 0);
- //std::cout << "radicand = " << radicand << std::endl;
- if(G < 0) // here we try to maximise the denominator avoiding cancellation
- a = - sqrt(radicand);
- else
- a = sqrt(radicand);
- //std::cout << "a = " << a << std::endl;
- a = n / (a + G);
- //std::cout << "a = " << a << std::endl;
- xk -= a;
- }
- //std::cout << "xk = " << xk << std::endl;
- return xk;
-}
-
-
-std::vector<cdouble >
-laguerre(Poly p, const double tol) {
- std::vector<cdouble > solutions;
- //std::cout << "p = " << p << " = ";
- while(p.size() > 1)
- {
- double x0 = 0;
- bool quad_root = false;
- cdouble sol = laguerre_internal_complex(p, x0, tol, quad_root);
- //if(abs(sol) > 1) break;
- Poly dvs;
- if(quad_root) {
- dvs.push_back((sol*conj(sol)).real());
- dvs.push_back(-(sol + conj(sol)).real());
- dvs.push_back(1.0);
- //std::cout << "(" << dvs << ")";
- //solutions.push_back(sol);
- //solutions.push_back(conj(sol));
- } else {
- //std::cout << sol << std::endl;
- dvs.push_back(-sol.real());
- dvs.push_back(1.0);
- solutions.push_back(sol);
- //std::cout << "(" << dvs << ")";
- }
- Poly r;
- p = divide(p, dvs, r);
- //std::cout << r << std::endl;
- }
- return solutions;
-}
-
-std::vector<double>
-laguerre_real_interval(Poly const & ply,
- const double lo, const double hi,
- const double tol) {
-}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+#include "poly-laguerre-solve.h"
+#include <iterator>
+
+typedef std::complex<double> cdouble;
+
+cdouble laguerre_internal_complex(Poly const & p,
+ double x0,
+ double tol,
+ bool & quad_root) {
+ cdouble a = 2*tol;
+ cdouble xk = x0;
+ double n = p.degree();
+ quad_root = false;
+ const unsigned shuffle_rate = 10;
+ static double shuffle[] = {0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 1.0};
+ unsigned shuffle_counter = 0;
+ while(std::norm(a) > (tol*tol)) {
+ //std::cout << "xk = " << xk << std::endl;
+ cdouble b = p.back();
+ cdouble d = 0, f = 0;
+ double err = abs(b);
+ double abx = abs(xk);
+ for(int j = p.size()-2; j >= 0; j--) {
+ f = xk*f + d;
+ d = xk*d + b;
+ b = xk*b + p[j];
+ err = abs(b) + abx*err;
+ }
+
+ err *= 1e-7; // magic epsilon for convergence, should be computed from tol
+
+ cdouble px = b;
+ if(abs(b) < err)
+ return xk;
+ //if(std::norm(px) < tol*tol)
+ // return xk;
+ cdouble G = d / px;
+ cdouble H = G*G - f / px;
+
+ //std::cout << "G = " << G << "H = " << H;
+ cdouble radicand = (n - 1)*(n*H-G*G);
+ //assert(radicand.real() > 0);
+ if(radicand.real() < 0)
+ quad_root = true;
+ //std::cout << "radicand = " << radicand << std::endl;
+ if(G.real() < 0) // here we try to maximise the denominator avoiding cancellation
+ a = - sqrt(radicand);
+ else
+ a = sqrt(radicand);
+ //std::cout << "a = " << a << std::endl;
+ a = n / (a + G);
+ //std::cout << "a = " << a << std::endl;
+ if(shuffle_counter % shuffle_rate == 0)
+ ;//a *= shuffle[shuffle_counter / shuffle_rate];
+ xk -= a;
+ shuffle_counter++;
+ if(shuffle_counter >= 90)
+ break;
+ }
+ //std::cout << "xk = " << xk << std::endl;
+ return xk;
+}
+
+double laguerre_internal(Poly const & p,
+ Poly const & pp,
+ Poly const & ppp,
+ double x0,
+ double tol,
+ bool & quad_root) {
+ double a = 2*tol;
+ double xk = x0;
+ double n = p.degree();
+ quad_root = false;
+ while(a*a > (tol*tol)) {
+ //std::cout << "xk = " << xk << std::endl;
+ double px = p(xk);
+ if(px*px < tol*tol)
+ return xk;
+ double G = pp(xk) / px;
+ double H = G*G - ppp(xk) / px;
+
+ //std::cout << "G = " << G << "H = " << H;
+ double radicand = (n - 1)*(n*H-G*G);
+ assert(radicand > 0);
+ //std::cout << "radicand = " << radicand << std::endl;
+ if(G < 0) // here we try to maximise the denominator avoiding cancellation
+ a = - sqrt(radicand);
+ else
+ a = sqrt(radicand);
+ //std::cout << "a = " << a << std::endl;
+ a = n / (a + G);
+ //std::cout << "a = " << a << std::endl;
+ xk -= a;
+ }
+ //std::cout << "xk = " << xk << std::endl;
+ return xk;
+}
+
+
+std::vector<cdouble >
+laguerre(Poly p, const double tol) {
+ std::vector<cdouble > solutions;
+ //std::cout << "p = " << p << " = ";
+ while(p.size() > 1)
+ {
+ double x0 = 0;
+ bool quad_root = false;
+ cdouble sol = laguerre_internal_complex(p, x0, tol, quad_root);
+ //if(abs(sol) > 1) break;
+ Poly dvs;
+ if(quad_root) {
+ dvs.push_back((sol*conj(sol)).real());
+ dvs.push_back(-(sol + conj(sol)).real());
+ dvs.push_back(1.0);
+ //std::cout << "(" << dvs << ")";
+ //solutions.push_back(sol);
+ //solutions.push_back(conj(sol));
+ } else {
+ //std::cout << sol << std::endl;
+ dvs.push_back(-sol.real());
+ dvs.push_back(1.0);
+ solutions.push_back(sol);
+ //std::cout << "(" << dvs << ")";
+ }
+ Poly r;
+ p = divide(p, dvs, r);
+ //std::cout << r << std::endl;
+ }
+ return solutions;
+}
+
+std::vector<double>
+laguerre_real_interval(Poly const & ply,
+ const double lo, const double hi,
+ const double tol) {
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/2geom/sweep.cpp b/src/2geom/sweep.cpp
index c0e1c3997..b9ef71b5c 100644
--- a/src/2geom/sweep.cpp
+++ b/src/2geom/sweep.cpp
@@ -1,105 +1,105 @@
-#include "sweep.h"
-
-#include <algorithm>
-
-namespace Geom {
-
-std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> rs) {
- std::vector<Event> events; events.reserve(rs.size()*2);
- std::vector<std::vector<unsigned> > pairs(rs.size());
-
- for(unsigned i = 0; i < rs.size(); i++) {
- events.push_back(Event(rs[i].left(), i, false));
- events.push_back(Event(rs[i].right(), i, true));
- }
- std::sort(events.begin(), events.end());
-
- std::vector<unsigned> open;
- for(unsigned i = 0; i < events.size(); i++) {
- unsigned ix = events[i].ix;
- if(events[i].closing) {
- std::vector<unsigned>::iterator iter = std::find(open.begin(), open.end(), ix);
- //if(iter != open.end())
- open.erase(iter);
- } else {
- for(unsigned j = 0; j < open.size(); j++) {
- unsigned jx = open[j];
- if(rs[jx][Y].intersects(rs[ix][Y])) {
- pairs[jx].push_back(ix);
- }
- }
- open.push_back(ix);
- }
- }
- return pairs;
-}
-
-std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> a, std::vector<Rect> b) {
- std::vector<std::vector<unsigned> > pairs(a.size());
- if(a.empty() || b.empty()) return pairs;
- std::vector<Event> events[2];
- events[0].reserve(a.size()*2);
- events[1].reserve(b.size()*2);
-
- for(unsigned n = 0; n < 2; n++) {
- unsigned sz = n ? b.size() : a.size();
- events[n].reserve(sz*2);
- for(unsigned i = 0; i < sz; i++) {
- events[n].push_back(Event(n ? b[i].left() : a[i].left(), i, false));
- events[n].push_back(Event(n ? b[i].right() : a[i].right(), i, true));
- }
- std::sort(events[n].begin(), events[n].end());
- }
-
- std::vector<unsigned> open[2];
- bool n = events[1].front() < events[0].front();
- for(unsigned i[] = {0,0}; i[n] < events[n].size();) {
- unsigned ix = events[n][i[n]].ix;
- bool closing = events[n][i[n]].closing;
- //std::cout << n << "[" << ix << "] - " << (closing ? "closer" : "opener") << "\n";
- if(closing) {
- open[n].erase(std::find(open[n].begin(), open[n].end(), ix));
- } else {
- if(n) {
- //n = 1
- //opening a B, add to all open a
- for(unsigned j = 0; j < open[0].size(); j++) {
- unsigned jx = open[0][j];
- if(a[jx][Y].intersects(b[ix][Y])) {
- pairs[jx].push_back(ix);
- }
- }
- } else {
- //n = 0
- //opening an A, add all open b
- for(unsigned j = 0; j < open[1].size(); j++) {
- unsigned jx = open[1][j];
- if(b[jx][Y].intersects(a[ix][Y])) {
- pairs[ix].push_back(jx);
- }
- }
- }
- open[n].push_back(ix);
- }
- i[n]++;
- if(i[n]>=events[n].size()) {break;}
- n = (events[!n][i[!n]] < events[n][i[n]]) ? !n : n;
- }
- return pairs;
-}
-
-//Fake cull, until the switch to the real sweep is made.
-std::vector<std::vector<unsigned> > fake_cull(unsigned a, unsigned b) {
- std::vector<std::vector<unsigned> > ret;
-
- std::vector<unsigned> all;
- for(unsigned j = 0; j < b; j++)
- all.push_back(j);
-
- for(unsigned i = 0; i < a; i++)
- ret.push_back(all);
-
- return ret;
-}
-
-}
+#include "sweep.h"
+
+#include <algorithm>
+
+namespace Geom {
+
+std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> rs) {
+ std::vector<Event> events; events.reserve(rs.size()*2);
+ std::vector<std::vector<unsigned> > pairs(rs.size());
+
+ for(unsigned i = 0; i < rs.size(); i++) {
+ events.push_back(Event(rs[i].left(), i, false));
+ events.push_back(Event(rs[i].right(), i, true));
+ }
+ std::sort(events.begin(), events.end());
+
+ std::vector<unsigned> open;
+ for(unsigned i = 0; i < events.size(); i++) {
+ unsigned ix = events[i].ix;
+ if(events[i].closing) {
+ std::vector<unsigned>::iterator iter = std::find(open.begin(), open.end(), ix);
+ //if(iter != open.end())
+ open.erase(iter);
+ } else {
+ for(unsigned j = 0; j < open.size(); j++) {
+ unsigned jx = open[j];
+ if(rs[jx][Y].intersects(rs[ix][Y])) {
+ pairs[jx].push_back(ix);
+ }
+ }
+ open.push_back(ix);
+ }
+ }
+ return pairs;
+}
+
+std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> a, std::vector<Rect> b) {
+ std::vector<std::vector<unsigned> > pairs(a.size());
+ if(a.empty() || b.empty()) return pairs;
+ std::vector<Event> events[2];
+ events[0].reserve(a.size()*2);
+ events[1].reserve(b.size()*2);
+
+ for(unsigned n = 0; n < 2; n++) {
+ unsigned sz = n ? b.size() : a.size();
+ events[n].reserve(sz*2);
+ for(unsigned i = 0; i < sz; i++) {
+ events[n].push_back(Event(n ? b[i].left() : a[i].left(), i, false));
+ events[n].push_back(Event(n ? b[i].right() : a[i].right(), i, true));
+ }
+ std::sort(events[n].begin(), events[n].end());
+ }
+
+ std::vector<unsigned> open[2];
+ bool n = events[1].front() < events[0].front();
+ for(unsigned i[] = {0,0}; i[n] < events[n].size();) {
+ unsigned ix = events[n][i[n]].ix;
+ bool closing = events[n][i[n]].closing;
+ //std::cout << n << "[" << ix << "] - " << (closing ? "closer" : "opener") << "\n";
+ if(closing) {
+ open[n].erase(std::find(open[n].begin(), open[n].end(), ix));
+ } else {
+ if(n) {
+ //n = 1
+ //opening a B, add to all open a
+ for(unsigned j = 0; j < open[0].size(); j++) {
+ unsigned jx = open[0][j];
+ if(a[jx][Y].intersects(b[ix][Y])) {
+ pairs[jx].push_back(ix);
+ }
+ }
+ } else {
+ //n = 0
+ //opening an A, add all open b
+ for(unsigned j = 0; j < open[1].size(); j++) {
+ unsigned jx = open[1][j];
+ if(b[jx][Y].intersects(a[ix][Y])) {
+ pairs[ix].push_back(jx);
+ }
+ }
+ }
+ open[n].push_back(ix);
+ }
+ i[n]++;
+ if(i[n]>=events[n].size()) {break;}
+ n = (events[!n][i[!n]] < events[n][i[n]]) ? !n : n;
+ }
+ return pairs;
+}
+
+//Fake cull, until the switch to the real sweep is made.
+std::vector<std::vector<unsigned> > fake_cull(unsigned a, unsigned b) {
+ std::vector<std::vector<unsigned> > ret;
+
+ std::vector<unsigned> all;
+ for(unsigned j = 0; j < b; j++)
+ all.push_back(j);
+
+ for(unsigned i = 0; i < a; i++)
+ ret.push_back(all);
+
+ return ret;
+}
+
+}
diff --git a/src/libgdl/gdl-win32.c b/src/libgdl/gdl-win32.c
index 044befedf..68df2f67d 100644
--- a/src/libgdl/gdl-win32.c
+++ b/src/libgdl/gdl-win32.c
@@ -1,42 +1,42 @@
-/*
- * Windows stuff
- *
- * Author:
- * Albin Sunnanbo
- * Based on code by Lauris Kaplinski <lauris@kaplinski.com> (/src/extension/internal/win32.cpp)
- *
- * This code is in public domain
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "gdl-win32.h"
-
-/* Platform detection */
-gboolean
-is_os_vista()
-{
- static gboolean initialized = FALSE;
- static gboolean is_vista = FALSE;
- static OSVERSIONINFOA osver;
-
- if ( !initialized )
- {
- BOOL result;
-
- initialized = TRUE;
-
- memset (&osver, 0, sizeof(OSVERSIONINFOA));
- osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- result = GetVersionExA (&osver);
- if (result)
- {
- if (osver.dwMajorVersion == WIN32_MAJORVERSION_VISTA)
- is_vista = TRUE;
- }
- }
-
- return is_vista;
-}
+/*
+ * Windows stuff
+ *
+ * Author:
+ * Albin Sunnanbo
+ * Based on code by Lauris Kaplinski <lauris@kaplinski.com> (/src/extension/internal/win32.cpp)
+ *
+ * This code is in public domain
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gdl-win32.h"
+
+/* Platform detection */
+gboolean
+is_os_vista()
+{
+ static gboolean initialized = FALSE;
+ static gboolean is_vista = FALSE;
+ static OSVERSIONINFOA osver;
+
+ if ( !initialized )
+ {
+ BOOL result;
+
+ initialized = TRUE;
+
+ memset (&osver, 0, sizeof(OSVERSIONINFOA));
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+ result = GetVersionExA (&osver);
+ if (result)
+ {
+ if (osver.dwMajorVersion == WIN32_MAJORVERSION_VISTA)
+ is_vista = TRUE;
+ }
+ }
+
+ return is_vista;
+}
diff --git a/src/libgdl/gdl-win32.h b/src/libgdl/gdl-win32.h
index 8fa0800ed..21361e982 100644
--- a/src/libgdl/gdl-win32.h
+++ b/src/libgdl/gdl-win32.h
@@ -1,30 +1,30 @@
-#ifndef __INKSCAPE_GDL_WIN32_H__
-#define __INKSCAPE_GDL_WIN32_H__
-
-/*
- * Windows stuff
- *
- * Author:
- * Albin Sunnanbo
- *
- * This code is in public domain
- */
-
-
-
-#define WIN32_MAJORVERSION_VISTA 0x0006
-
-
-
-#include <config.h>
-#include <windows.h>
-#include <gdk/gdk.h>
-
-#ifndef WIN32
-#error "This file is only usable for Windows"
-#endif
-
-/* Platform detection */
-gboolean is_os_vista();
-
-#endif /* __INKSCAPE_GDL_WIN32_H__ */
+#ifndef __INKSCAPE_GDL_WIN32_H__
+#define __INKSCAPE_GDL_WIN32_H__
+
+/*
+ * Windows stuff
+ *
+ * Author:
+ * Albin Sunnanbo
+ *
+ * This code is in public domain
+ */
+
+
+
+#define WIN32_MAJORVERSION_VISTA 0x0006
+
+
+
+#include <config.h>
+#include <windows.h>
+#include <gdk/gdk.h>
+
+#ifndef WIN32
+#error "This file is only usable for Windows"
+#endif
+
+/* Platform detection */
+gboolean is_os_vista();
+
+#endif /* __INKSCAPE_GDL_WIN32_H__ */
diff --git a/src/live_effects/parameter/path-reference.cpp b/src/live_effects/parameter/path-reference.cpp
index 6a48f446b..78f270e64 100644
--- a/src/live_effects/parameter/path-reference.cpp
+++ b/src/live_effects/parameter/path-reference.cpp
@@ -1,53 +1,53 @@
-/*
- * The reference corresponding to href of LPE Path parameter.
- *
- * Copyright (C) 2008 Johan Engelen
- *
- * Released under GNU GPL, read the file 'COPYING' for more information.
- */
-
-#include "live_effects/parameter/path-reference.h"
-
-#include <cstring>
-#include <string>
-#include <string.h>
-
-#include "enums.h"
-
-#include "display/curve.h"
-#include "livarot/Path.h"
-#include "prefs-utils.h"
-#include "sp-shape.h"
-#include "sp-text.h"
-#include "uri.h"
-
-namespace Inkscape {
-namespace LivePathEffect {
-
-bool PathReference::_acceptObject(SPObject * const obj) const
-{
- if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj)) {
- /* Refuse references to lpeobject */
- if (obj == getOwner()) {
- return false;
- }
- // TODO: check whether the referred path has this LPE applied, if so: deny deny deny!
- return true;
- } else {
- return false;
- }
-}
-
-} // namespace LivePathEffect
-} // namespace Inkscape
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+/*
+ * The reference corresponding to href of LPE Path parameter.
+ *
+ * Copyright (C) 2008 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include "live_effects/parameter/path-reference.h"
+
+#include <cstring>
+#include <string>
+#include <string.h>
+
+#include "enums.h"
+
+#include "display/curve.h"
+#include "livarot/Path.h"
+#include "prefs-utils.h"
+#include "sp-shape.h"
+#include "sp-text.h"
+#include "uri.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+bool PathReference::_acceptObject(SPObject * const obj) const
+{
+ if (SP_IS_SHAPE(obj) || SP_IS_TEXT(obj)) {
+ /* Refuse references to lpeobject */
+ if (obj == getOwner()) {
+ return false;
+ }
+ // TODO: check whether the referred path has this LPE applied, if so: deny deny deny!
+ return true;
+ } else {
+ return false;
+ }
+}
+
+} // namespace LivePathEffect
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/live_effects/parameter/path-reference.h b/src/live_effects/parameter/path-reference.h
index 88147d908..67508e531 100644
--- a/src/live_effects/parameter/path-reference.h
+++ b/src/live_effects/parameter/path-reference.h
@@ -1,60 +1,60 @@
-#ifndef SEEN_LPE_PATH_REFERENCE_H
-#define SEEN_LPE_PATH_REFERENCE_H
-
-/*
- * The reference corresponding to href of LPE PathParam.
- *
- * Copyright (C) 2008 Johan Engelen
- *
- * Released under GNU GPL, read the file 'COPYING' for more information.
- */
-
-#include <forward.h>
-#include <uri-references.h>
-#include <sigc++/sigc++.h>
-
-class Path;
-
-namespace Inkscape {
-
-namespace XML {
- struct Node;
-}
-
-namespace LivePathEffect {
-
-
-class PathReference : public Inkscape::URIReference {
-public:
- PathReference(SPObject *owner) : URIReference(owner) {}
-
- SPItem *getObject() const {
- return (SPItem *)URIReference::getObject();
- }
-
-protected:
- virtual bool _acceptObject(SPObject * const obj) const;
-
-private:
- PathReference(const PathReference&);
- PathReference& operator=(const PathReference&);
-};
-
-} // namespace LivePathEffect
-
-} // namespace Inkscape
-
-
-
-#endif /* !SEEN_LPE_PATH_REFERENCE_H */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+#ifndef SEEN_LPE_PATH_REFERENCE_H
+#define SEEN_LPE_PATH_REFERENCE_H
+
+/*
+ * The reference corresponding to href of LPE PathParam.
+ *
+ * Copyright (C) 2008 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information.
+ */
+
+#include <forward.h>
+#include <uri-references.h>
+#include <sigc++/sigc++.h>
+
+class Path;
+
+namespace Inkscape {
+
+namespace XML {
+ struct Node;
+}
+
+namespace LivePathEffect {
+
+
+class PathReference : public Inkscape::URIReference {
+public:
+ PathReference(SPObject *owner) : URIReference(owner) {}
+
+ SPItem *getObject() const {
+ return (SPItem *)URIReference::getObject();
+ }
+
+protected:
+ virtual bool _acceptObject(SPObject * const obj) const;
+
+private:
+ PathReference(const PathReference&);
+ PathReference& operator=(const PathReference&);
+};
+
+} // namespace LivePathEffect
+
+} // namespace Inkscape
+
+
+
+#endif /* !SEEN_LPE_PATH_REFERENCE_H */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/live_effects/parameter/pointparam-knotholder.cpp b/src/live_effects/parameter/pointparam-knotholder.cpp
index cf6e00c22..55cb81209 100644
--- a/src/live_effects/parameter/pointparam-knotholder.cpp
+++ b/src/live_effects/parameter/pointparam-knotholder.cpp
@@ -1,201 +1,201 @@
-#define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C
-
-/*
- * Container for PointParamKnotHolder visual handles
- *
- * Authors:
- * Johan Engelen <goejendaagh@zonnet.nl>
- *
- * Copyright (C) 2008 authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "live_effects/parameter/pointparam-knotholder.h"
-#include "live_effects/lpeobject.h"
-#include "document.h"
-#include "sp-shape.h"
-#include "knot.h"
-#include "knotholder.h"
-#include "knot-holder-entity.h"
-
-#include <libnr/nr-matrix-div.h>
-#include <glibmm/i18n.h>
-#include <2geom/point.h>
-#include <2geom/matrix.h>
-#include "svg/stringstream.h"
-#include "xml/repr.h"
-
-class SPDesktop;
-
-namespace Inkscape {
-
-static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh);
-static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh);
-static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh);
-static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass);
-
-void pointparam_knot_holder_dispose(GObject *object);
-
-static SPKnotHolderClass *parent_class;
-
-/**
- * Registers PointParamKnotHolder class and returns its type number.
- */
-GType pointparam_knot_holder_get_type()
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof(PointParamKnotHolderClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) pointparam_knot_holder_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (PointParamKnotHolder),
- 16, /* n_preallocs */
- NULL,
- NULL
- };
- type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0);
- }
- return type;
-}
-
-/**
- * PointParamKnotHolder vtable initialization.
- */
-static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass *) klass;
-
- parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass);
- gobject_class->dispose = pointparam_knot_holder_dispose;
-}
-
-PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item)
-{
- g_return_val_if_fail(desktop != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(SP_IS_ITEM(item), NULL);
-
- PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0);
- knot_holder->desktop = desktop;
- knot_holder->item = item;
- knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject);
- g_object_ref(G_OBJECT(item));
- g_object_ref(G_OBJECT(lpeobject));
- knot_holder->entity = NULL;
-
- knot_holder->released = NULL;
-
- knot_holder->repr = lpeobject->repr;
- knot_holder->repr_key = key;
-
- knot_holder->local_change = FALSE;
-
- return knot_holder;
-}
-
-void pointparam_knot_holder_dispose(GObject *object) {
- PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder);
-
- g_object_unref(G_OBJECT(kh->item));
- g_object_unref(G_OBJECT(kh->lpeobject));
- while (kh->entity) {
- SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
- g_signal_handler_disconnect(e->knot, e->_click_handler_id);
- g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);
- /* unref should call destroy */
- g_object_unref(e->knot);
- g_free(e);
- kh->entity = g_slist_remove(kh->entity, e);
- }
-}
-
-void
-PointParamKnotHolder::add_knot (
- Geom::Point & p,
- PointParamKnotHolderClickedFunc knot_click,
- SPKnotShapeType shape,
- SPKnotModeType mode,
- guint32 color,
- const gchar *tip )
-{
- /* create new SPKnotHolderEntry */
- SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1);
- e->knot = sp_knot_new(desktop, tip);
- e->knot_set = NULL;
- e->knot_get = NULL;
- if (knot_click) {
- e->knot_click = knot_click;
- } else {
- e->knot_click = NULL;
- }
-
- g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL);
- g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL);
-
- e->knot->fill [SP_KNOT_STATE_NORMAL] = color;
- g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL);
-
- entity = g_slist_append(entity, e);
-
- /* Move to current point. */
- NR::Point dp = p * sp_item_i2d_affine(item);
- sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
-
- e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this);
- e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this);
- e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this);
-
- sp_knot_show(e->knot);
-}
-
-static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/)
-{
-
-}
-
-/**
- * \param p In desktop coordinates.
- * This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect
- */
-static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh)
-{
- NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
- NR::Point pos = (*p) / i2d;
-
- Inkscape::SVGOStringStream os;
- os << pos.to_2geom();
-
- kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str());
-}
-
-static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh)
-{
- NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
- NR::Point pos = sp_knot_position(knot) / i2d;
-
- Inkscape::SVGOStringStream os;
- os << pos.to_2geom();
-
- kh->repr->setAttribute(kh->repr_key , os.str().c_str());
-
- sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_LPE, _("Change LPE point parameter"));
-}
-
-} // namespace Inkscape
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+#define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_C
+
+/*
+ * Container for PointParamKnotHolder visual handles
+ *
+ * Authors:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2008 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/parameter/pointparam-knotholder.h"
+#include "live_effects/lpeobject.h"
+#include "document.h"
+#include "sp-shape.h"
+#include "knot.h"
+#include "knotholder.h"
+#include "knot-holder-entity.h"
+
+#include <libnr/nr-matrix-div.h>
+#include <glibmm/i18n.h>
+#include <2geom/point.h>
+#include <2geom/matrix.h>
+#include "svg/stringstream.h"
+#include "xml/repr.h"
+
+class SPDesktop;
+
+namespace Inkscape {
+
+static void pointparam_knot_clicked_handler (SPKnot *knot, guint state, PointParamKnotHolder *kh);
+static void pointparam_knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, PointParamKnotHolder *kh);
+static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh);
+static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass);
+
+void pointparam_knot_holder_dispose(GObject *object);
+
+static SPKnotHolderClass *parent_class;
+
+/**
+ * Registers PointParamKnotHolder class and returns its type number.
+ */
+GType pointparam_knot_holder_get_type()
+{
+ static GType type = 0;
+ if (!type) {
+ GTypeInfo info = {
+ sizeof(PointParamKnotHolderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) pointparam_knot_holder_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PointParamKnotHolder),
+ 16, /* n_preallocs */
+ NULL,
+ NULL
+ };
+ type = g_type_register_static (G_TYPE_OBJECT, "InkscapePointParamKnotHolder", &info, (GTypeFlags) 0);
+ }
+ return type;
+}
+
+/**
+ * PointParamKnotHolder vtable initialization.
+ */
+static void pointparam_knot_holder_class_init(PointParamKnotHolderClass *klass)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass *) klass;
+
+ parent_class = (SPKnotHolderClass*) g_type_class_peek_parent(klass);
+ gobject_class->dispose = pointparam_knot_holder_dispose;
+}
+
+PointParamKnotHolder *pointparam_knot_holder_new(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item)
+{
+ g_return_val_if_fail(desktop != NULL, NULL);
+ g_return_val_if_fail(item != NULL, NULL);
+ g_return_val_if_fail(SP_IS_ITEM(item), NULL);
+
+ PointParamKnotHolder *knot_holder = (PointParamKnotHolder*)g_object_new (INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, 0);
+ knot_holder->desktop = desktop;
+ knot_holder->item = item;
+ knot_holder->lpeobject = LIVEPATHEFFECT(lpeobject);
+ g_object_ref(G_OBJECT(item));
+ g_object_ref(G_OBJECT(lpeobject));
+ knot_holder->entity = NULL;
+
+ knot_holder->released = NULL;
+
+ knot_holder->repr = lpeobject->repr;
+ knot_holder->repr_key = key;
+
+ knot_holder->local_change = FALSE;
+
+ return knot_holder;
+}
+
+void pointparam_knot_holder_dispose(GObject *object) {
+ PointParamKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), INKSCAPE_TYPE_POINTPARAM_KNOT_HOLDER, PointParamKnotHolder);
+
+ g_object_unref(G_OBJECT(kh->item));
+ g_object_unref(G_OBJECT(kh->lpeobject));
+ while (kh->entity) {
+ SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
+ g_signal_handler_disconnect(e->knot, e->_click_handler_id);
+ g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);
+ /* unref should call destroy */
+ g_object_unref(e->knot);
+ g_free(e);
+ kh->entity = g_slist_remove(kh->entity, e);
+ }
+}
+
+void
+PointParamKnotHolder::add_knot (
+ Geom::Point & p,
+ PointParamKnotHolderClickedFunc knot_click,
+ SPKnotShapeType shape,
+ SPKnotModeType mode,
+ guint32 color,
+ const gchar *tip )
+{
+ /* create new SPKnotHolderEntry */
+ SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1);
+ e->knot = sp_knot_new(desktop, tip);
+ e->knot_set = NULL;
+ e->knot_get = NULL;
+ if (knot_click) {
+ e->knot_click = knot_click;
+ } else {
+ e->knot_click = NULL;
+ }
+
+ g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL);
+ g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL);
+
+ e->knot->fill [SP_KNOT_STATE_NORMAL] = color;
+ g_object_set (G_OBJECT (e->knot->item), "fill_color", color, NULL);
+
+ entity = g_slist_append(entity, e);
+
+ /* Move to current point. */
+ NR::Point dp = p * sp_item_i2d_affine(item);
+ sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
+
+ e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(pointparam_knot_moved_handler), this);
+ e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(pointparam_knot_clicked_handler), this);
+ e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(pointparam_knot_ungrabbed_handler), this);
+
+ sp_knot_show(e->knot);
+}
+
+static void pointparam_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, PointParamKnotHolder */*kh*/)
+{
+
+}
+
+/**
+ * \param p In desktop coordinates.
+ * This function does not write to XML, but tries to write directly to the PointParam to quickly live update the effect
+ */
+static void pointparam_knot_moved_handler(SPKnot */*knot*/, NR::Point const *p, guint /*state*/, PointParamKnotHolder *kh)
+{
+ NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
+ NR::Point pos = (*p) / i2d;
+
+ Inkscape::SVGOStringStream os;
+ os << pos.to_2geom();
+
+ kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str());
+}
+
+static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh)
+{
+ NR::Matrix const i2d(sp_item_i2d_affine(kh->item));
+ NR::Point pos = sp_knot_position(knot) / i2d;
+
+ Inkscape::SVGOStringStream os;
+ os << pos.to_2geom();
+
+ kh->repr->setAttribute(kh->repr_key , os.str().c_str());
+
+ sp_document_done(SP_OBJECT_DOCUMENT (kh->lpeobject), SP_VERB_CONTEXT_LPE, _("Change LPE point parameter"));
+}
+
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
index 373d641cb..78055eb9c 100644
--- a/src/sp-lpe-item.cpp
+++ b/src/sp-lpe-item.cpp
@@ -1,451 +1,451 @@
-#define __SP_LPE_ITEM_CPP__
-
-/** \file
- * Base class for live path effect items
- */
-/*
- * Authors:
- * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
- * Bastien Bouclet <bgkweb@gmail.com>
- *
- * Copyright (C) 2008 authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "live_effects/effect.h"
-#include "live_effects/lpeobject.h"
-#include "live_effects/lpeobject-reference.h"
-
-#include "sp-path.h"
-#include "sp-item-group.h"
-#include "macros.h"
-#include "attributes.h"
-#include "sp-lpe-item.h"
-#include "xml/repr.h"
-#include "uri.h"
-
-/* LPEItem base class */
-
-static void sp_lpe_item_class_init(SPLPEItemClass *klass);
-static void sp_lpe_item_init(SPLPEItem *lpe_item);
-static void sp_lpe_item_finalize(GObject *object);
-
-static void sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-static void sp_lpe_item_release(SPObject *object);
-static void sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value);
-static void sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_lpe_item_modified (SPObject *object, unsigned int flags);
-static Inkscape::XML::Node *sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
-
-static void sp_lpe_item_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);
-static void sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child);
-
-static void lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem);
-static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem);
-
-static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem);
-static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem);
-
-static SPItemClass *parent_class;
-
-GType
-sp_lpe_item_get_type()
-{
- static GType lpe_item_type = 0;
-
- if (!lpe_item_type) {
- GTypeInfo lpe_item_info = {
- sizeof(SPLPEItemClass),
- NULL, NULL,
- (GClassInitFunc) sp_lpe_item_class_init,
- NULL, NULL,
- sizeof(SPLPEItem),
- 16,
- (GInstanceInitFunc) sp_lpe_item_init,
- NULL, /* value_table */
- };
- lpe_item_type = g_type_register_static(SP_TYPE_ITEM, "SPLPEItem", &lpe_item_info, (GTypeFlags)0);
- }
- return lpe_item_type;
-}
-
-static void
-sp_lpe_item_class_init(SPLPEItemClass *klass)
-{
- GObjectClass *gobject_class;
- SPObjectClass *sp_object_class;
-
- gobject_class = (GObjectClass *) klass;
- sp_object_class = (SPObjectClass *) klass;
- parent_class = (SPItemClass *)g_type_class_peek_parent (klass);
-
- gobject_class->finalize = sp_lpe_item_finalize;
-
- sp_object_class->build = sp_lpe_item_build;
- sp_object_class->release = sp_lpe_item_release;
- sp_object_class->set = sp_lpe_item_set;
- sp_object_class->update = sp_lpe_item_update;
- sp_object_class->modified = sp_lpe_item_modified;
- sp_object_class->write = sp_lpe_item_write;
- sp_object_class->child_added = sp_lpe_item_child_added;
- sp_object_class->remove_child = sp_lpe_item_remove_child;
-
- klass->update_patheffect = NULL;
-}
-
-static void
-sp_lpe_item_init(SPLPEItem *lpeitem)
-{
- lpeitem->path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(SP_OBJECT(lpeitem));
- new (&lpeitem->lpe_modified_connection) sigc::connection();
-}
-
-static void
-sp_lpe_item_finalize(GObject *object)
-{
- if (((GObjectClass *) (parent_class))->finalize) {
- (* ((GObjectClass *) (parent_class))->finalize)(object);
- }
-}
-
-/**
- * Reads the Inkscape::XML::Node, and initializes SPLPEItem variables. For this to get called,
- * our name must be associated with a repr via "sp_object_type_register". Best done through
- * sp-object-repr.cpp's repr_name_entries array.
- */
-static void
-sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
-{
- SP_LPE_ITEM(object)->path_effect_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobject_ref_changed), SP_LPE_ITEM(object)));
-
- sp_object_read_attr(object, "inkscape:path-effect");
-
- if (((SPObjectClass *) parent_class)->build) {
- ((SPObjectClass *) parent_class)->build(object, document, repr);
- }
-}
-
-/**
- * Drops any allocated memory.
- */
-static void
-sp_lpe_item_release(SPObject *object)
-{
- SPLPEItem *lpeitem;
- lpeitem = (SPLPEItem *) object;
-
- lpeitem->path_effect_ref->detach();
-
- lpeitem->lpe_modified_connection.disconnect();
- lpeitem->lpe_modified_connection.~connection();
-
- if (((SPObjectClass *) parent_class)->release)
- ((SPObjectClass *) parent_class)->release(object);
-}
-
-/**
- * Sets a specific value in the SPLPEItem.
- */
-static void
-sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value)
-{
- SPLPEItem *lpeitem = (SPLPEItem *) object;
-
- switch (key) {
- case SP_ATTR_INKSCAPE_PATH_EFFECT:
- if ( value && lpeitem->path_effect_ref->lpeobject_href
- && ( strcmp(value, lpeitem->path_effect_ref->lpeobject_href) == 0 ) ) {
- /* No change, do nothing. */
- } else {
- if (value) {
- // Now do the attaching, which emits the changed signal.
- try {
- lpeitem->path_effect_ref->link((gchar*)value);
- } catch (Inkscape::BadURIException &e) {
- g_warning("%s", e.what());
- lpeitem->path_effect_ref->detach();
- }
- } else {
- // Detach, which emits the changed signal.
- lpeitem->path_effect_ref->detach();
- }
- }
- break;
- default:
- if (((SPObjectClass *) parent_class)->set) {
- ((SPObjectClass *) parent_class)->set(object, key, value);
- }
- break;
- }
-}
-
-/**
- * Receives update notifications.
- */
-static void
-sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags)
-{
- if (((SPObjectClass *) parent_class)->update) {
- ((SPObjectClass *) parent_class)->update(object, ctx, flags);
- }
-}
-
-/**
- * Sets modified flag for all sub-item views.
- */
-static void
-sp_lpe_item_modified (SPObject *object, unsigned int flags)
-{
- if (((SPObjectClass *) (parent_class))->modified) {
- (* ((SPObjectClass *) (parent_class))->modified) (object, flags);
- }
-}
-
-/**
- * Writes its settings to an incoming repr object, if any.
- */
-static Inkscape::XML::Node *
-sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
-{
- SPLPEItem *lpeitem = (SPLPEItem *) object;
-
- if ( sp_lpe_item_has_path_effect(lpeitem) ) {
- repr->setAttribute("inkscape:path-effect", lpeitem->path_effect_ref->lpeobject_href);
- } else {
- repr->setAttribute("inkscape:path-effect", NULL);
- }
-
- if (((SPObjectClass *)(parent_class))->write) {
- ((SPObjectClass *)(parent_class))->write(object, repr, flags);
- }
-
- return repr;
-}
-
-
-LivePathEffectObject *
-sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem) {
- if (!lpeitem) return NULL;
-
- if (sp_lpe_item_has_path_effect(lpeitem)) {
- return lpeitem->path_effect_ref->lpeobject;
- } else {
- return NULL;
- }
-}
-
-Inkscape::LivePathEffect::Effect *
-sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem) {
- if (!lpeitem) return NULL;
-
- LivePathEffectObject * lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
- if (lpeobj)
- return lpeobj->lpe;
- else
- return NULL;
-}
-
-void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) {
- if (!lpeitem) return;
- if (!curve) return;
-
- if (sp_lpe_item_has_path_effect(lpeitem)) {
- LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
- lpeobj->lpe->doEffect(curve);
- }
-
- SPObject *parent = lpeitem->parent;
- if (parent && SP_IS_LPE_ITEM(parent))
- sp_lpe_item_perform_path_effect(SP_LPE_ITEM(parent), curve);
-}
-
-/**
- * Calls any registered handlers for the update_patheffect action
- */
-void
-sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write)
-{
-#ifdef SHAPE_VERBOSE
- g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem);
-#endif
- g_return_if_fail (lpeitem != NULL);
- g_return_if_fail (SP_IS_LPE_ITEM (lpeitem));
-
- if (sp_lpe_item_has_path_effect(lpeitem)) {
- LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
- lpeobj->lpe->doBeforeEffect(lpeitem);
- }
-
- if (SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect) {
- SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect (lpeitem, write);
- }
-}
-
-/**
- * Gets called when (re)attached to another lpeobject.
- */
-static void
-lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem)
-{
- if (old_ref) {
- sp_signal_disconnect_by_data(old_ref, lpeitem);
- }
- if ( IS_LIVEPATHEFFECT(ref) && ref != lpeitem )
- {
- lpeitem->lpe_modified_connection.disconnect();
- lpeitem->lpe_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), lpeitem));
- lpeobject_ref_modified(ref, 0, lpeitem);
- }
-}
-
-/**
- * Gets called when lpeobject repr contents change: i.e. parameter change.
- */
-static void
-lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem)
-{
- sp_lpe_item_update_patheffect (lpeitem, true);
-}
-
-static void
-sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)
-{
- if (SP_IS_GROUP(lpeitem)) {
- GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
- for ( GSList const *iter = item_list; iter; iter = iter->next ) {
- SPObject *subitem = static_cast<SPObject *>(iter->data);
- if (SP_IS_LPE_ITEM(subitem)) {
- sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem));
- }
- }
- }
- else if (SP_IS_PATH(lpeitem)) {
- Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(lpeitem);
- if ( !pathrepr->attribute("inkscape:original-d") ) {
- pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
- }
- }
-}
-
-static void
-sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem)
-{
- if (SP_IS_GROUP(lpeitem)) {
- GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
- for ( GSList const *iter = item_list; iter; iter = iter->next ) {
- SPObject *subitem = static_cast<SPObject *>(iter->data);
- if (SP_IS_LPE_ITEM(subitem)) {
- sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem));
- }
- }
- }
- else if (SP_IS_PATH(lpeitem)) {
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);
- if (!sp_lpe_item_has_path_effect_recursive(lpeitem)
- && repr->attribute("inkscape:original-d")) {
- repr->setAttribute("d", repr->attribute("inkscape:original-d"));
- repr->setAttribute("inkscape:original-d", NULL);
- }
- else {
- sp_lpe_item_update_patheffect(lpeitem, true);
- }
- }
-}
-
-void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value)
-{
- if (!value) {
- sp_lpe_item_remove_path_effect(lpeitem, false);
- } else {
- SP_OBJECT_REPR(lpeitem)->setAttribute("inkscape:path-effect", value);
-
- // make sure there is an original-d for paths!!!
- sp_lpe_item_create_original_path_recursive(lpeitem);
- }
-}
-
-void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj)
-{
- const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");
- gchar *hrefstr = g_strdup_printf("#%s", repr_id);
- sp_lpe_item_set_path_effect(lpeitem, hrefstr);
- g_free(hrefstr);
-}
-
-void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths)
-{
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);
- repr->setAttribute("inkscape:path-effect", NULL);
-
- if (!keep_paths) {
- sp_lpe_item_cleanup_original_path_recursive(lpeitem);
- }
-}
-
-bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem)
-{
- return lpeitem->path_effect_ref && lpeitem->path_effect_ref->lpeobject;
-}
-
-bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem)
-{
- SPObject *parent = lpeitem->parent;
- if (parent && SP_IS_LPE_ITEM(parent)) {
- return sp_lpe_item_has_path_effect(lpeitem) || sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(parent));
- }
- else {
- return sp_lpe_item_has_path_effect(lpeitem);
- }
-}
-
-void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt)
-{
- LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
- if (lpeobj && lpeobj->lpe) {
- lpeobj->lpe->editNextParamOncanvas(SP_ITEM(lpeitem), dt);
- }
-}
-
-static void
-sp_lpe_item_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
-{
- if (((SPObjectClass *) (parent_class))->child_added)
- (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref);
-
- if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
- SPObject *ochild = sp_object_get_child_by_repr(object, child);
- if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
- sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild));
- }
- }
-}
-
-static void
-sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child)
-{
- if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
- SPObject *ochild = sp_object_get_child_by_repr(object, child);
- if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
- sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild));
- }
- }
-
- if (((SPObjectClass *) (parent_class))->remove_child)
- (* ((SPObjectClass *) (parent_class))->remove_child) (object, child);
-}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+#define __SP_LPE_ITEM_CPP__
+
+/** \file
+ * Base class for live path effect items
+ */
+/*
+ * Authors:
+ * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ * Bastien Bouclet <bgkweb@gmail.com>
+ *
+ * Copyright (C) 2008 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "live_effects/effect.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/lpeobject-reference.h"
+
+#include "sp-path.h"
+#include "sp-item-group.h"
+#include "macros.h"
+#include "attributes.h"
+#include "sp-lpe-item.h"
+#include "xml/repr.h"
+#include "uri.h"
+
+/* LPEItem base class */
+
+static void sp_lpe_item_class_init(SPLPEItemClass *klass);
+static void sp_lpe_item_init(SPLPEItem *lpe_item);
+static void sp_lpe_item_finalize(GObject *object);
+
+static void sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_lpe_item_release(SPObject *object);
+static void sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value);
+static void sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags);
+static void sp_lpe_item_modified (SPObject *object, unsigned int flags);
+static Inkscape::XML::Node *sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static void sp_lpe_item_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);
+static void sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child);
+
+static void lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem);
+static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem);
+
+static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem);
+static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem);
+
+static SPItemClass *parent_class;
+
+GType
+sp_lpe_item_get_type()
+{
+ static GType lpe_item_type = 0;
+
+ if (!lpe_item_type) {
+ GTypeInfo lpe_item_info = {
+ sizeof(SPLPEItemClass),
+ NULL, NULL,
+ (GClassInitFunc) sp_lpe_item_class_init,
+ NULL, NULL,
+ sizeof(SPLPEItem),
+ 16,
+ (GInstanceInitFunc) sp_lpe_item_init,
+ NULL, /* value_table */
+ };
+ lpe_item_type = g_type_register_static(SP_TYPE_ITEM, "SPLPEItem", &lpe_item_info, (GTypeFlags)0);
+ }
+ return lpe_item_type;
+}
+
+static void
+sp_lpe_item_class_init(SPLPEItemClass *klass)
+{
+ GObjectClass *gobject_class;
+ SPObjectClass *sp_object_class;
+
+ gobject_class = (GObjectClass *) klass;
+ sp_object_class = (SPObjectClass *) klass;
+ parent_class = (SPItemClass *)g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = sp_lpe_item_finalize;
+
+ sp_object_class->build = sp_lpe_item_build;
+ sp_object_class->release = sp_lpe_item_release;
+ sp_object_class->set = sp_lpe_item_set;
+ sp_object_class->update = sp_lpe_item_update;
+ sp_object_class->modified = sp_lpe_item_modified;
+ sp_object_class->write = sp_lpe_item_write;
+ sp_object_class->child_added = sp_lpe_item_child_added;
+ sp_object_class->remove_child = sp_lpe_item_remove_child;
+
+ klass->update_patheffect = NULL;
+}
+
+static void
+sp_lpe_item_init(SPLPEItem *lpeitem)
+{
+ lpeitem->path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(SP_OBJECT(lpeitem));
+ new (&lpeitem->lpe_modified_connection) sigc::connection();
+}
+
+static void
+sp_lpe_item_finalize(GObject *object)
+{
+ if (((GObjectClass *) (parent_class))->finalize) {
+ (* ((GObjectClass *) (parent_class))->finalize)(object);
+ }
+}
+
+/**
+ * Reads the Inkscape::XML::Node, and initializes SPLPEItem variables. For this to get called,
+ * our name must be associated with a repr via "sp_object_type_register". Best done through
+ * sp-object-repr.cpp's repr_name_entries array.
+ */
+static void
+sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
+{
+ SP_LPE_ITEM(object)->path_effect_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobject_ref_changed), SP_LPE_ITEM(object)));
+
+ sp_object_read_attr(object, "inkscape:path-effect");
+
+ if (((SPObjectClass *) parent_class)->build) {
+ ((SPObjectClass *) parent_class)->build(object, document, repr);
+ }
+}
+
+/**
+ * Drops any allocated memory.
+ */
+static void
+sp_lpe_item_release(SPObject *object)
+{
+ SPLPEItem *lpeitem;
+ lpeitem = (SPLPEItem *) object;
+
+ lpeitem->path_effect_ref->detach();
+
+ lpeitem->lpe_modified_connection.disconnect();
+ lpeitem->lpe_modified_connection.~connection();
+
+ if (((SPObjectClass *) parent_class)->release)
+ ((SPObjectClass *) parent_class)->release(object);
+}
+
+/**
+ * Sets a specific value in the SPLPEItem.
+ */
+static void
+sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value)
+{
+ SPLPEItem *lpeitem = (SPLPEItem *) object;
+
+ switch (key) {
+ case SP_ATTR_INKSCAPE_PATH_EFFECT:
+ if ( value && lpeitem->path_effect_ref->lpeobject_href
+ && ( strcmp(value, lpeitem->path_effect_ref->lpeobject_href) == 0 ) ) {
+ /* No change, do nothing. */
+ } else {
+ if (value) {
+ // Now do the attaching, which emits the changed signal.
+ try {
+ lpeitem->path_effect_ref->link((gchar*)value);
+ } catch (Inkscape::BadURIException &e) {
+ g_warning("%s", e.what());
+ lpeitem->path_effect_ref->detach();
+ }
+ } else {
+ // Detach, which emits the changed signal.
+ lpeitem->path_effect_ref->detach();
+ }
+ }
+ break;
+ default:
+ if (((SPObjectClass *) parent_class)->set) {
+ ((SPObjectClass *) parent_class)->set(object, key, value);
+ }
+ break;
+ }
+}
+
+/**
+ * Receives update notifications.
+ */
+static void
+sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags)
+{
+ if (((SPObjectClass *) parent_class)->update) {
+ ((SPObjectClass *) parent_class)->update(object, ctx, flags);
+ }
+}
+
+/**
+ * Sets modified flag for all sub-item views.
+ */
+static void
+sp_lpe_item_modified (SPObject *object, unsigned int flags)
+{
+ if (((SPObjectClass *) (parent_class))->modified) {
+ (* ((SPObjectClass *) (parent_class))->modified) (object, flags);
+ }
+}
+
+/**
+ * Writes its settings to an incoming repr object, if any.
+ */
+static Inkscape::XML::Node *
+sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ SPLPEItem *lpeitem = (SPLPEItem *) object;
+
+ if ( sp_lpe_item_has_path_effect(lpeitem) ) {
+ repr->setAttribute("inkscape:path-effect", lpeitem->path_effect_ref->lpeobject_href);
+ } else {
+ repr->setAttribute("inkscape:path-effect", NULL);
+ }
+
+ if (((SPObjectClass *)(parent_class))->write) {
+ ((SPObjectClass *)(parent_class))->write(object, repr, flags);
+ }
+
+ return repr;
+}
+
+
+LivePathEffectObject *
+sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem) {
+ if (!lpeitem) return NULL;
+
+ if (sp_lpe_item_has_path_effect(lpeitem)) {
+ return lpeitem->path_effect_ref->lpeobject;
+ } else {
+ return NULL;
+ }
+}
+
+Inkscape::LivePathEffect::Effect *
+sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem) {
+ if (!lpeitem) return NULL;
+
+ LivePathEffectObject * lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
+ if (lpeobj)
+ return lpeobj->lpe;
+ else
+ return NULL;
+}
+
+void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) {
+ if (!lpeitem) return;
+ if (!curve) return;
+
+ if (sp_lpe_item_has_path_effect(lpeitem)) {
+ LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
+ lpeobj->lpe->doEffect(curve);
+ }
+
+ SPObject *parent = lpeitem->parent;
+ if (parent && SP_IS_LPE_ITEM(parent))
+ sp_lpe_item_perform_path_effect(SP_LPE_ITEM(parent), curve);
+}
+
+/**
+ * Calls any registered handlers for the update_patheffect action
+ */
+void
+sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write)
+{
+#ifdef SHAPE_VERBOSE
+ g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem);
+#endif
+ g_return_if_fail (lpeitem != NULL);
+ g_return_if_fail (SP_IS_LPE_ITEM (lpeitem));
+
+ if (sp_lpe_item_has_path_effect(lpeitem)) {
+ LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
+ lpeobj->lpe->doBeforeEffect(lpeitem);
+ }
+
+ if (SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect) {
+ SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect (lpeitem, write);
+ }
+}
+
+/**
+ * Gets called when (re)attached to another lpeobject.
+ */
+static void
+lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem)
+{
+ if (old_ref) {
+ sp_signal_disconnect_by_data(old_ref, lpeitem);
+ }
+ if ( IS_LIVEPATHEFFECT(ref) && ref != lpeitem )
+ {
+ lpeitem->lpe_modified_connection.disconnect();
+ lpeitem->lpe_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), lpeitem));
+ lpeobject_ref_modified(ref, 0, lpeitem);
+ }
+}
+
+/**
+ * Gets called when lpeobject repr contents change: i.e. parameter change.
+ */
+static void
+lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem)
+{
+ sp_lpe_item_update_patheffect (lpeitem, true);
+}
+
+static void
+sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)
+{
+ if (SP_IS_GROUP(lpeitem)) {
+ GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
+ for ( GSList const *iter = item_list; iter; iter = iter->next ) {
+ SPObject *subitem = static_cast<SPObject *>(iter->data);
+ if (SP_IS_LPE_ITEM(subitem)) {
+ sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem));
+ }
+ }
+ }
+ else if (SP_IS_PATH(lpeitem)) {
+ Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(lpeitem);
+ if ( !pathrepr->attribute("inkscape:original-d") ) {
+ pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
+ }
+ }
+}
+
+static void
+sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem)
+{
+ if (SP_IS_GROUP(lpeitem)) {
+ GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
+ for ( GSList const *iter = item_list; iter; iter = iter->next ) {
+ SPObject *subitem = static_cast<SPObject *>(iter->data);
+ if (SP_IS_LPE_ITEM(subitem)) {
+ sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem));
+ }
+ }
+ }
+ else if (SP_IS_PATH(lpeitem)) {
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);
+ if (!sp_lpe_item_has_path_effect_recursive(lpeitem)
+ && repr->attribute("inkscape:original-d")) {
+ repr->setAttribute("d", repr->attribute("inkscape:original-d"));
+ repr->setAttribute("inkscape:original-d", NULL);
+ }
+ else {
+ sp_lpe_item_update_patheffect(lpeitem, true);
+ }
+ }
+}
+
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value)
+{
+ if (!value) {
+ sp_lpe_item_remove_path_effect(lpeitem, false);
+ } else {
+ SP_OBJECT_REPR(lpeitem)->setAttribute("inkscape:path-effect", value);
+
+ // make sure there is an original-d for paths!!!
+ sp_lpe_item_create_original_path_recursive(lpeitem);
+ }
+}
+
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj)
+{
+ const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");
+ gchar *hrefstr = g_strdup_printf("#%s", repr_id);
+ sp_lpe_item_set_path_effect(lpeitem, hrefstr);
+ g_free(hrefstr);
+}
+
+void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths)
+{
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);
+ repr->setAttribute("inkscape:path-effect", NULL);
+
+ if (!keep_paths) {
+ sp_lpe_item_cleanup_original_path_recursive(lpeitem);
+ }
+}
+
+bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem)
+{
+ return lpeitem->path_effect_ref && lpeitem->path_effect_ref->lpeobject;
+}
+
+bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem)
+{
+ SPObject *parent = lpeitem->parent;
+ if (parent && SP_IS_LPE_ITEM(parent)) {
+ return sp_lpe_item_has_path_effect(lpeitem) || sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(parent));
+ }
+ else {
+ return sp_lpe_item_has_path_effect(lpeitem);
+ }
+}
+
+void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt)
+{
+ LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
+ if (lpeobj && lpeobj->lpe) {
+ lpeobj->lpe->editNextParamOncanvas(SP_ITEM(lpeitem), dt);
+ }
+}
+
+static void
+sp_lpe_item_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+{
+ if (((SPObjectClass *) (parent_class))->child_added)
+ (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref);
+
+ if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
+ SPObject *ochild = sp_object_get_child_by_repr(object, child);
+ if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
+ sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild));
+ }
+ }
+}
+
+static void
+sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child)
+{
+ if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {
+ SPObject *ochild = sp_object_get_child_by_repr(object, child);
+ if ( ochild && SP_IS_LPE_ITEM(ochild) ) {
+ sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild));
+ }
+ }
+
+ if (((SPObjectClass *) (parent_class))->remove_child)
+ (* ((SPObjectClass *) (parent_class))->remove_child) (object, child);
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h
index a818eeb53..d05b75cd0 100644
--- a/src/sp-lpe-item.h
+++ b/src/sp-lpe-item.h
@@ -1,69 +1,69 @@
-#ifndef SP_LPE_ITEM_H_SEEN
-#define SP_LPE_ITEM_H_SEEN
-
-/** \file
- * Base class for live path effect items
- */
-/*
- * Authors:
- * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
- * Bastien Bouclet <bgkweb@gmail.com>
- *
- * Copyright (C) 2008 authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "sp-item.h"
-#include "display/curve.h"
-
-#define SP_TYPE_LPE_ITEM (sp_lpe_item_get_type())
-#define SP_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_LPE_ITEM, SPLPEItem))
-#define SP_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_LPE_ITEM, SPLPEItemClass))
-#define SP_IS_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_LPE_ITEM))
-#define SP_IS_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_LPE_ITEM))
-
-struct LivePathEffectObject;
-namespace Inkscape{
-namespace LivePathEffect{
- class LPEObjectReference;
- class Effect;
-};
-};
-
-struct SPLPEItem : public SPItem {
- Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref;
- sigc::connection lpe_modified_connection;
-};
-
-struct SPLPEItemClass {
- SPItemClass parent_class;
-
- void (* update_patheffect) (SPLPEItem *lpeitem, bool write);
-};
-
-GType sp_lpe_item_get_type();
-
-LivePathEffectObject * sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem);
-Inkscape::LivePathEffect::Effect * sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem);
-void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write);
-void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve);
-void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value);
-void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj);
-void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths);
-bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem);
-bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem);
-void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt);
-
-#endif /* !SP_LPE_ITEM_H_SEEN */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+#ifndef SP_LPE_ITEM_H_SEEN
+#define SP_LPE_ITEM_H_SEEN
+
+/** \file
+ * Base class for live path effect items
+ */
+/*
+ * Authors:
+ * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ * Bastien Bouclet <bgkweb@gmail.com>
+ *
+ * Copyright (C) 2008 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-item.h"
+#include "display/curve.h"
+
+#define SP_TYPE_LPE_ITEM (sp_lpe_item_get_type())
+#define SP_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_LPE_ITEM, SPLPEItem))
+#define SP_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_LPE_ITEM, SPLPEItemClass))
+#define SP_IS_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_LPE_ITEM))
+#define SP_IS_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_LPE_ITEM))
+
+struct LivePathEffectObject;
+namespace Inkscape{
+namespace LivePathEffect{
+ class LPEObjectReference;
+ class Effect;
+};
+};
+
+struct SPLPEItem : public SPItem {
+ Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref;
+ sigc::connection lpe_modified_connection;
+};
+
+struct SPLPEItemClass {
+ SPItemClass parent_class;
+
+ void (* update_patheffect) (SPLPEItem *lpeitem, bool write);
+};
+
+GType sp_lpe_item_get_type();
+
+LivePathEffectObject * sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem);
+Inkscape::LivePathEffect::Effect * sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem);
+void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write);
+void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve);
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value);
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj);
+void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths);
+bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem);
+bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem);
+void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt);
+
+#endif /* !SP_LPE_ITEM_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :