From 019dcd82834b28a0204655ae1f3766a4c4d7cb7c Mon Sep 17 00:00:00 2001 From: pjrm Date: Sat, 29 Mar 2008 09:49:50 +0000 Subject: [PATCH] svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). --- src/2geom/angle.h | 100 +- src/2geom/poly-dk-solve.cpp | 128 +-- src/2geom/poly-laguerre-solve.cpp | 294 +++--- src/2geom/sweep.cpp | 210 ++-- src/libgdl/gdl-win32.c | 84 +- src/libgdl/gdl-win32.h | 60 +- src/live_effects/parameter/path-reference.cpp | 106 +- src/live_effects/parameter/path-reference.h | 120 +-- .../parameter/pointparam-knotholder.cpp | 402 ++++---- src/sp-lpe-item.cpp | 902 +++++++++--------- src/sp-lpe-item.h | 138 +-- 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 - * - * 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 + * + * 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 - -/*** implementation of the Durand-Kerner method. seems buggy*/ - -std::complex evalu(Poly const & p, std::complex x) { - std::complex result = 0; - std::complex xx = 1; - - for(unsigned i = 0; i < p.size(); i++) { - result += p[i]*xx; - xx *= x; - } - return result; -} - -std::vector > DK(Poly const & ply, const double tol) { - std::vector > roots; - const int N = ply.degree(); - - std::complex b(0.4, 0.9); - std::complex 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 denom = 1; - std::complex 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 dr = evalu(ply, R)/denom; - error += norm(dr); - roots[r_i] = R - dr; - } - /*std::copy(roots.begin(), roots.end(), std::ostream_iterator >(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 + +/*** implementation of the Durand-Kerner method. seems buggy*/ + +std::complex evalu(Poly const & p, std::complex x) { + std::complex result = 0; + std::complex xx = 1; + + for(unsigned i = 0; i < p.size(); i++) { + result += p[i]*xx; + xx *= x; + } + return result; +} + +std::vector > DK(Poly const & ply, const double tol) { + std::vector > roots; + const int N = ply.degree(); + + std::complex b(0.4, 0.9); + std::complex 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 denom = 1; + std::complex 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 dr = evalu(ply, R)/denom; + error += norm(dr); + roots[r_i] = R - dr; + } + /*std::copy(roots.begin(), roots.end(), std::ostream_iterator >(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 - -typedef std::complex 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 -laguerre(Poly p, const double tol) { - std::vector 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 -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 + +typedef std::complex 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 +laguerre(Poly p, const double tol) { + std::vector 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 +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 - -namespace Geom { - -std::vector > sweep_bounds(std::vector rs) { - std::vector events; events.reserve(rs.size()*2); - std::vector > 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 open; - for(unsigned i = 0; i < events.size(); i++) { - unsigned ix = events[i].ix; - if(events[i].closing) { - std::vector::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 > sweep_bounds(std::vector a, std::vector b) { - std::vector > pairs(a.size()); - if(a.empty() || b.empty()) return pairs; - std::vector 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 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 > fake_cull(unsigned a, unsigned b) { - std::vector > ret; - - std::vector 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 + +namespace Geom { + +std::vector > sweep_bounds(std::vector rs) { + std::vector events; events.reserve(rs.size()*2); + std::vector > 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 open; + for(unsigned i = 0; i < events.size(); i++) { + unsigned ix = events[i].ix; + if(events[i].closing) { + std::vector::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 > sweep_bounds(std::vector a, std::vector b) { + std::vector > pairs(a.size()); + if(a.empty() || b.empty()) return pairs; + std::vector 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 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 > fake_cull(unsigned a, unsigned b) { + std::vector > ret; + + std::vector 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 (/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 (/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 -#include -#include - -#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 +#include +#include + +#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 -#include -#include - -#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 +#include +#include + +#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 -#include -#include - -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 +#include +#include + +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 - * - * 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 -#include -#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 + * + * 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 +#include +#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 - * Bastien Bouclet - * - * 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(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(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 + * Bastien Bouclet + * + * 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(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(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 - * Bastien Bouclet - * - * 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 + * Bastien Bouclet + * + * 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 : -- 2.30.2