Code

svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging...
authorpjrm <pjrm@users.sourceforge.net>
Sat, 29 Mar 2008 09:49:50 +0000 (09:49 +0000)
committerpjrm <pjrm@users.sourceforge.net>
Sat, 29 Mar 2008 09:49:50 +0000 (09:49 +0000)
src/2geom/angle.h
src/2geom/poly-dk-solve.cpp
src/2geom/poly-laguerre-solve.cpp
src/2geom/sweep.cpp
src/libgdl/gdl-win32.c
src/libgdl/gdl-win32.h
src/live_effects/parameter/path-reference.cpp
src/live_effects/parameter/path-reference.h
src/live_effects/parameter/pointparam-knotholder.cpp
src/sp-lpe-item.cpp
src/sp-lpe-item.h

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