diff options
Diffstat (limited to 'src')
373 files changed, 4896 insertions, 7908 deletions
diff --git a/src/2geom/bezier-curve.h b/src/2geom/bezier-curve.h index 135aa4f71..589335d22 100644 --- a/src/2geom/bezier-curve.h +++ b/src/2geom/bezier-curve.h @@ -104,15 +104,16 @@ public: void setPoint(unsigned ix, Point v) { inner[X].setPoint(ix, v[X]); inner[Y].setPoint(ix, v[Y]); } Point const operator[](unsigned ix) const { return Point(inner[X][ix], inner[Y][ix]); } - Rect boundsFast() const { return bounds_fast(inner); } - Rect boundsExact() const { return bounds_exact(inner); } - Rect boundsLocal(Interval i, unsigned deg) const { - if(i.min() == 0 && i.max() == 1) return boundsFast(); + virtual OptRect boundsFast() const { return bounds_fast(inner); } + virtual OptRect boundsExact() const { return bounds_exact(inner); } + virtual OptRect boundsLocal(OptInterval i, unsigned deg) const { + if (!i) return OptRect(); + if(i->min() == 0 && i->max() == 1) return boundsFast(); if(deg == 0) return bounds_local(inner, i); // TODO: UUUUUUGGGLLY - if(deg == 1 && order > 1) return Rect(bounds_local(Geom::derivative(inner[X]), i), - bounds_local(Geom::derivative(inner[Y]), i)); - return Rect(Interval(0,0), Interval(0,0)); + if(deg == 1 && order > 1) return OptRect(bounds_local(Geom::derivative(inner[X]), i), + bounds_local(Geom::derivative(inner[Y]), i)); + return OptRect(); } //TODO: local diff --git a/src/2geom/bezier.h b/src/2geom/bezier.h index 94dd909ca..889dde9ed 100644 --- a/src/2geom/bezier.h +++ b/src/2geom/bezier.h @@ -72,7 +72,7 @@ private: friend Bezier portion(const Bezier & a, Coord from, Coord to); - friend Interval bounds_fast(Bezier const & b); + friend OptInterval bounds_fast(Bezier const & b); friend Bezier derivative(const Bezier & a); @@ -185,10 +185,9 @@ public: std::vector<Coord> valueAndDerivatives(Coord t, unsigned n_derivs) const { std::vector<Coord> val_n_der; Coord d_[order()+1]; - unsigned nn = n_derivs + 1; // the size of the result vector equals n_derivs+1 + unsigned nn = n_derivs + 1; // the size of the result vector equals n_derivs+1 ... if(nn > order()) - //nn = order(); - nn = order()+1; + nn = order()+1; // .. but with a maximum of order() + 1! for(unsigned i = 0; i < size(); i++) d_[i] = c_[i]; for(unsigned di = 0; di < nn; di++) { @@ -309,18 +308,22 @@ inline Bezier integral(const Bezier & a) { return inte; } -inline Interval bounds_fast(Bezier const & b) { +inline OptInterval bounds_fast(Bezier const & b) { return Interval::fromArray(&b.c_[0], b.size()); } //TODO: better bounds exact -inline Interval bounds_exact(Bezier const & b) { +inline OptInterval bounds_exact(Bezier const & b) { return bounds_exact(b.toSBasis()); } -inline Interval bounds_local(Bezier const & b, Interval i) { - return bounds_fast(portion(b, i.min(), i.max())); +inline OptInterval bounds_local(Bezier const & b, OptInterval i) { //return bounds_local(b.toSBasis(), i); + if (i) { + return bounds_fast(portion(b, i->min(), i->max())); + } else { + return OptInterval(); + } } inline std::ostream &operator<< (std::ostream &out_file, const Bezier & b) { diff --git a/src/2geom/concepts.h b/src/2geom/concepts.h index 8f4d98ef2..9c57db44d 100644 --- a/src/2geom/concepts.h +++ b/src/2geom/concepts.h @@ -37,21 +37,20 @@ #include <2geom/point.h> #include <vector> #include <boost/concept_check.hpp> +#include <2geom/forward.h> namespace Geom { //forward decls -template <typename T> class D2; - template <typename T> struct ResultTraits; template <> struct ResultTraits<double> { - typedef Interval bounds_type; + typedef OptInterval bounds_type; typedef SBasis sb_type; }; template <> struct ResultTraits<Point > { - typedef D2<Interval> bounds_type; + typedef OptRect bounds_type; typedef D2<SBasis> sb_type; }; diff --git a/src/2geom/crossing.h b/src/2geom/crossing.h index 291f69382..3ad034ac9 100644 --- a/src/2geom/crossing.h +++ b/src/2geom/crossing.h @@ -120,7 +120,12 @@ typedef std::vector<Crossings> CrossingSet; template<typename C> std::vector<Rect> bounds(C const &a) { std::vector<Rect> rs; - for(unsigned i = 0; i < a.size(); i++) rs.push_back(a[i].boundsFast()); + for (unsigned i = 0; i < a.size(); i++) { + OptRect bb = a[i].boundsFast(); + if (bb) { + rs.push_back(*bb); + } + } return rs; } diff --git a/src/2geom/curve.h b/src/2geom/curve.h index b81548ba8..af02d6edb 100644 --- a/src/2geom/curve.h +++ b/src/2geom/curve.h @@ -74,10 +74,10 @@ public: virtual Curve *duplicate() const = 0; - virtual Rect boundsFast() const = 0; - virtual Rect boundsExact() const = 0; - virtual Rect boundsLocal(Interval i, unsigned deg) const = 0; - Rect boundsLocal(Interval i) const { return boundsLocal(i, 0); } + virtual OptRect boundsFast() const = 0; + virtual OptRect boundsExact() const = 0; + virtual OptRect boundsLocal(OptInterval i, unsigned deg) const = 0; + OptRect boundsLocal(OptInterval i) const { return boundsLocal(i, 0); } virtual std::vector<double> roots(double v, Dim2 d) const = 0; @@ -133,12 +133,12 @@ public: */ virtual Point unitTangentAt(Coord t, unsigned n = 3) const { - for (unsigned deriv_n = 1; deriv_n <= n; deriv_n++) { - Point deriv = pointAndDerivatives(t, deriv_n)[deriv_n]; - Coord length = deriv.length(); + std::vector<Point> derivs = pointAndDerivatives(t, n); + for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) { + Coord length = derivs[deriv_n].length(); if ( ! are_near(length, 0) ) { // length of derivative is non-zero, so return unit vector - return deriv / length; + derivs[deriv_n] / length; } } return Point (0,0); diff --git a/src/2geom/d2-sbasis.cpp b/src/2geom/d2-sbasis.cpp index 01f83bf5e..55c7ef55e 100644 --- a/src/2geom/d2-sbasis.cpp +++ b/src/2geom/d2-sbasis.cpp @@ -150,6 +150,81 @@ split_at_discontinuities (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwsbi return ret; } +static void set_first_point(Piecewise<D2<SBasis> > &f, Point a){ + if ( f.empty() ){ + f.concat(Piecewise<D2<SBasis> >(D2<SBasis>(Linear(a[X]),Linear(a[Y])))); + return; + } + for (unsigned dim=0; dim<2; dim++){ + if (f.segs.front()[dim].size() == 0){ + f.segs.front()[dim].push_back(Linear(a[dim],0)); + }else{ + f.segs.front()[dim][0][0] = a[dim]; + } + } +} +static void set_last_point(Piecewise<D2<SBasis> > &f, Point a){ + if ( f.empty() ){ + f.concat(Piecewise<D2<SBasis> >(D2<SBasis>(Linear(a[X]),Linear(a[Y])))); + return; + } + for (unsigned dim=0; dim<2; dim++){ + if (f.segs.back()[dim].size() == 0){ + f.segs.back()[dim].push_back(Linear(0,a[dim])); + }else{ + f.segs.back()[dim][0][1] = a[dim]; + } + } +} + +std::vector<Piecewise<D2<SBasis> > > fuse_nearby_ends(std::vector<Piecewise<D2<SBasis> > > const &f, double tol){ + + if ( f.size()==0 ) return f; + std::vector<Piecewise<D2<SBasis> > > result; + std::vector<std::vector<unsigned> > pre_result; + for (unsigned i=0; i<f.size(); i++){ + bool inserted = false; + Point a = f[i].firstValue(); + Point b = f[i].lastValue(); + for (unsigned j=0; j<pre_result.size(); j++){ + Point aj = f.at(pre_result[j].back()).lastValue(); + Point bj = f.at(pre_result[j].front()).firstValue(); + if ( L2(a-aj) < tol ) { + pre_result[j].push_back(i); + inserted = true; + break; + } + if ( L2(b-bj) < tol ) { + pre_result[j].insert(pre_result[j].begin(),i); + inserted = true; + break; + } + } + if (!inserted) { + pre_result.push_back(std::vector<unsigned>()); + pre_result.back().push_back(i); + } + } + for (unsigned i=0; i<pre_result.size(); i++){ + Piecewise<D2<SBasis> > comp; + for (unsigned j=0; j<pre_result[i].size(); j++){ + Piecewise<D2<SBasis> > new_comp = f.at(pre_result[i][j]); + if ( j>0 ){ + set_first_point( new_comp, comp.segs.back().at1() ); + } + comp.concat(new_comp); + } + if ( L2(comp.firstValue()-comp.lastValue()) < tol ){ + //TODO: check sizes!!! + set_last_point( comp, comp.segs.front().at0() ); + } + result.push_back(comp); + } + return result; + return f; +} + + } // namespace Geom diff --git a/src/2geom/d2-sbasis.h b/src/2geom/d2-sbasis.h index dd1a8e11c..c61052da7 100644 --- a/src/2geom/d2-sbasis.h +++ b/src/2geom/d2-sbasis.h @@ -79,6 +79,8 @@ Piecewise<D2<SBasis> > operator*(Piecewise<D2<SBasis> > const &a, Matrix const & Piecewise<D2<SBasis> > force_continuity(Piecewise<D2<SBasis> > const &f, double tol=0, bool closed=false); +std::vector<Piecewise<D2<SBasis> > > fuse_nearby_ends(std::vector<Piecewise<D2<SBasis> > > const &f, double tol=0); + std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > split_at_discontinuities (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwsbin, double tol = .0001); class CoordIterator @@ -114,13 +116,25 @@ inline CoordIterator iterateCoord(Piecewise<D2<SBasis> > const &a, unsigned d) { } //bounds specializations with order -inline Rect bounds_fast(D2<SBasis> const & s, unsigned order=0) { - return Rect(bounds_fast(s[X], order), - bounds_fast(s[Y], order)); +inline OptRect bounds_fast(D2<SBasis> const & s, unsigned order=0) { + OptRect retval; + OptInterval xint = bounds_fast(s[X], order); + if (xint) { + OptInterval yint = bounds_fast(s[Y], order); + if (yint) { + retval = Rect(*xint, *yint); + } + } + return retval; } -inline Rect bounds_local(D2<SBasis> const & s, Interval i, unsigned order=0) { - return Rect(bounds_local(s[X], i, order), - bounds_local(s[Y], i, order)); +inline OptRect bounds_local(D2<SBasis> const & s, OptInterval i, unsigned order=0) { + OptRect retval; + OptInterval xint = bounds_local(s[X], i, order); + OptInterval yint = bounds_local(s[Y], i, order); + if (xint && yint) { + retval = Rect(*xint, *yint); + } + return retval; } } diff --git a/src/2geom/d2.h b/src/2geom/d2.h index 7e2bbae53..a14e3b0eb 100644 --- a/src/2geom/d2.h +++ b/src/2geom/d2.h @@ -400,19 +400,19 @@ namespace Geom{ //Some D2 Fragment implementation which requires rect: template <typename T> -Rect bounds_fast(const D2<T> &a) { - boost::function_requires<FragmentConcept<T> >(); - return Rect(bounds_fast(a[X]), bounds_fast(a[Y])); +OptRect bounds_fast(const D2<T> &a) { + boost::function_requires<FragmentConcept<T> >(); + return OptRect(bounds_fast(a[X]), bounds_fast(a[Y])); } template <typename T> -Rect bounds_exact(const D2<T> &a) { - boost::function_requires<FragmentConcept<T> >(); - return Rect(bounds_exact(a[X]), bounds_exact(a[Y])); +OptRect bounds_exact(const D2<T> &a) { + boost::function_requires<FragmentConcept<T> >(); + return OptRect(bounds_exact(a[X]), bounds_exact(a[Y])); } template <typename T> -Rect bounds_local(const D2<T> &a, const Interval &t) { - boost::function_requires<FragmentConcept<T> >(); - return Rect(bounds_local(a[X], t), bounds_local(a[Y], t)); +OptRect bounds_local(const D2<T> &a, const OptInterval &t) { + boost::function_requires<FragmentConcept<T> >(); + return OptRect(bounds_local(a[X], t), bounds_local(a[Y], t)); } }; diff --git a/src/2geom/elliptical-arc.cpp b/src/2geom/elliptical-arc.cpp index bf2b72b63..f2b6b6be2 100644 --- a/src/2geom/elliptical-arc.cpp +++ b/src/2geom/elliptical-arc.cpp @@ -31,6 +31,7 @@ #include <2geom/elliptical-arc.h> #include <2geom/bezier-curve.h> #include <2geom/poly.h> +#include <2geom/sbasis-math.h> #include <cfloat> #include <limits> @@ -42,7 +43,7 @@ namespace Geom { -Rect EllipticalArc::boundsExact() const +OptRect EllipticalArc::boundsExact() const { std::vector<double> extremes(4); double cosrot = std::cos(rotation_angle()); diff --git a/src/2geom/elliptical-arc.h b/src/2geom/elliptical-arc.h index 24b4fcf46..25c79a363 100644 --- a/src/2geom/elliptical-arc.h +++ b/src/2geom/elliptical-arc.h @@ -168,17 +168,17 @@ class EllipticalArc : public Curve } - Rect boundsFast() const + virtual OptRect boundsFast() const { - return boundsExact(); + return boundsExact(); } - Rect boundsExact() const; + virtual OptRect boundsExact() const; // TODO: native implementation of the following methods - Rect boundsLocal(Interval i, unsigned int deg) const + virtual OptRect boundsLocal(OptInterval i, unsigned int deg) const { - return SBasisCurve(toSBasis()).boundsLocal(i, deg); + return SBasisCurve(toSBasis()).boundsLocal(i, deg); } std::vector<double> roots(double v, Dim2 d) const; diff --git a/src/2geom/forward.h b/src/2geom/forward.h index 184801ef4..15740faf0 100644 --- a/src/2geom/forward.h +++ b/src/2geom/forward.h @@ -62,6 +62,7 @@ class NotInvertible; class ContinuityError; class Interval; +class OptInterval; class Linear; class Hat; class Tri; @@ -81,6 +82,7 @@ class SBasis; class SBasisCurve; typedef D2<Interval> Rect; +class OptRect; class Shape; class Region; diff --git a/src/2geom/geom.cpp b/src/2geom/geom.cpp index d0689981a..f9b1a664b 100644 --- a/src/2geom/geom.cpp +++ b/src/2geom/geom.cpp @@ -9,6 +9,7 @@ #include <2geom/geom.h> #include <2geom/point.h> #include <algorithm> +#include <2geom/rect.h> namespace Geom { @@ -313,6 +314,14 @@ rect_line_intersect(Geom::Point const &c0, Geom::Point const &c1, return results; } +std::vector<Geom::Point> +rect_line_intersect(Geom::Rect &r, + Geom::Point const &p0, Geom::Point const &p1) +{ + return rect_line_intersect(r.min(), r.max(), p0, p1); +} + + /** * polyCentroid: Calculates the centroid (xCentroid, yCentroid) and area of a polygon, given its * vertices (x[0], y[0]) ... (x[n-1], y[n-1]). It is assumed that the contour is closed, i.e., that diff --git a/src/2geom/geom.h b/src/2geom/geom.h index aeb40f7e1..d0af7d7d2 100644 --- a/src/2geom/geom.h +++ b/src/2geom/geom.h @@ -38,6 +38,7 @@ #include <vector> #include <2geom/point.h> +#include <2geom/rect.h> namespace Geom { @@ -73,6 +74,11 @@ std::vector<Geom::Point> rect_line_intersect(Geom::Point const &E, Geom::Point const &F, Geom::Point const &p0, Geom::Point const &p1); + +std::vector<Geom::Point> +rect_line_intersect(Geom::Rect &r, + Geom::Point const &p0, Geom::Point const &p1); + int centroid(std::vector<Geom::Point> p, Geom::Point& centroid, double &area); } diff --git a/src/2geom/hvlinesegment.h b/src/2geom/hvlinesegment.h index 3e1287682..ccb95afdb 100644 --- a/src/2geom/hvlinesegment.h +++ b/src/2geom/hvlinesegment.h @@ -116,17 +116,17 @@ class HLineSegment : public Curve m_line_seg.setFinal( Point(finalPoint()[X], _y) ); } - Rect boundsFast() const + virtual OptRect boundsFast() const { return boundsExact(); } - Rect boundsExact() const + virtual OptRect boundsExact() const { return Rect( initialPoint(), finalPoint() ); } - Rect boundsLocal(Interval i, unsigned deg) const + virtual OptRect boundsLocal(OptInterval i, unsigned deg) const { return m_line_seg.boundsLocal(i, deg); } @@ -355,17 +355,17 @@ class VLineSegment : public Curve m_line_seg.setFinal( Point(_x, finalPoint()[Y]) ); } - Rect boundsFast() const + virtual OptRect boundsFast() const { return boundsExact(); } - Rect boundsExact() const + virtual OptRect boundsExact() const { return Rect( initialPoint(), finalPoint() ); } - Rect boundsLocal(Interval i, unsigned deg) const + virtual OptRect boundsLocal(OptInterval i, unsigned deg) const { return m_line_seg.boundsLocal(i, deg); } diff --git a/src/2geom/interval.h b/src/2geom/interval.h index 8f7a0b2a1..009528586 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -44,17 +44,20 @@ namespace Geom { -/* Although an Interval where _b[0] > _b[1] is considered empty, for proper functioning of other methods, - * a proper empty Interval is [+infinity, -infinity]. Then, expandTo(p) will set the interval to [p,p]. +class Interval; + +/** + * \brief This class represents a range of numbers that is never empty. + * + * The endpoints are included in the range. */ class Interval { private: Coord _b[2]; public: - // The default constructor creates an empty interval, that ranges from +infinity to -infinity. - // Doing an expandTo(p) on this empty interval will correctly set the whole interval to [p,p]. - explicit Interval() { _b[0] = +infinity(); _b[1] = -infinity(); } + /// The default constructor creates an interval [0,0] DO NOT RELY ON THIS, BEST NOT TO USE THIS CONSTRUCTOR + explicit Interval() { _b[0] = 0; _b[1] = 0; } explicit Interval(Coord u) { _b[0] = _b[1] = u; } /* When creating an Interval using the constructor specifying the exact range, the created interval * will be [u,v] when u<=v ; and will be [v,u] when v < u !!! @@ -78,7 +81,8 @@ public: inline Coord extent() const { return _b[1] - _b[0]; } inline Coord middle() const { return (_b[1] + _b[0]) * 0.5; } - inline bool isEmpty() const { return _b[0] > _b[1]; } +// inline bool isEmpty() const { return _b[0] > _b[1]; } + inline bool isSingular() const { return _b[0] == _b[1]; } inline bool contains(Coord val) const { return _b[0] <= val && val <= _b[1]; } bool contains(const Interval & val) const { return _b[0] <= val._b[0] && val._b[1] <= _b[1]; } bool intersects(const Interval & val) const { @@ -167,9 +171,15 @@ public: return result; } + /** When this would create an empty interval, the interval will be the centerpoint of the old range only. + */ inline void expandBy(double amnt) { _b[0] -= amnt; _b[1] += amnt; + if (_b[0] > _b[1]) { + Coord halfway = (_b[0]+_b[1])/2; + _b[0] = _b[1] = halfway; + } } inline void unionWith(const Interval & a) { @@ -214,12 +224,42 @@ inline Interval unify(const Interval & a, const Interval & b) { return Interval(std::min(a.min(), b.min()), std::max(a.max(), b.max())); } -inline boost::optional<Interval> intersect(const Interval & a, const Interval & b) { + +/** + * \brief OptInterval is an Interval that can be empty. + */ +class OptInterval : public boost::optional<Interval> { +public: + OptInterval() : boost::optional<Interval>() {}; + OptInterval(Interval const &a) : boost::optional<Interval>(a) {}; + OptInterval(Coord u) : boost::optional<Interval>(Interval(u)) {}; + OptInterval(Coord u, Coord v) : boost::optional<Interval>(Interval(u,v)) {}; + + /** + * Check whether this OptInterval is empty or not. + */ + inline bool isEmpty() { return (*this == false); }; + + /** + * If \c this is empty, copy argument \c a. Otherwise, union with it (and do nothing when \c a is empty) + */ + inline void unionWith(const OptInterval & a) { + if (a) { + if (*this) { // check that we are not empty + (*this)->unionWith(*a); + } else { + *this = a; + } + } + } +}; + +inline OptInterval intersect(const Interval & a, const Interval & b) { Coord u = std::max(a.min(), b.min()), v = std::min(a.max(), b.max()); //technically >= might be incorrect, but singulars suck - return u >= v ? boost::optional<Interval>() - : boost::optional<Interval>(Interval(u, v)); + return u >= v ? OptInterval() + : OptInterval(Interval(u, v)); } } diff --git a/src/2geom/linear.h b/src/2geom/linear.h index 4594e17be..e8828b283 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -37,6 +37,15 @@ #include <2geom/interval.h> #include <2geom/isnan.h> + +//#define USE_SBASIS_OF + +#ifdef USE_SBASIS_OF + +#include "linear-of.h" + +#else + namespace Geom{ inline double lerp(double t, double a, double b) { return a*(1-t) + b*t; } @@ -100,9 +109,9 @@ public: //defined in sbasis.h inline SBasis toSBasis() const; - inline Interval bounds_exact() const { return Interval(a[0], a[1]); } - inline Interval bounds_fast() const { return bounds_exact(); } - inline Interval bounds_local(double u, double v) const { return Interval(valueAt(u), valueAt(v)); } + inline OptInterval bounds_exact() const { return Interval(a[0], a[1]); } + inline OptInterval bounds_fast() const { return bounds_exact(); } + inline OptInterval bounds_local(double u, double v) const { return Interval(valueAt(u), valueAt(v)); } operator Tri() const { return a[1] - a[0]; @@ -169,7 +178,9 @@ inline Linear operator/=(Linear & a, double b) { a[0] /= b; a[1] /= b; return a; } -}; + +} +#endif #endif //SEEN_LINEAR_H diff --git a/src/2geom/nearest-point.cpp b/src/2geom/nearest-point.cpp index 705767f13..71beab9cb 100644 --- a/src/2geom/nearest-point.cpp +++ b/src/2geom/nearest-point.cpp @@ -50,34 +50,34 @@ namespace Geom */ double nearest_point( Point const& p, - D2<SBasis> const& c, - D2<SBasis> const& dc, - double from, double to ) + D2<SBasis> const& c, + D2<SBasis> const& dc, + double from, double to ) { - if ( from > to ) std::swap(from, to); - if ( from < 0 || to > 1 ) - { - THROW_RANGEERROR("[from,to] interval out of bounds"); - } - if (c.isConstant()) return from; - SBasis dd = dot(c - p, dc); - std::vector<double> zeros = Geom::roots(dd); + if ( from > to ) std::swap(from, to); + if ( from < 0 || to > 1 ) + { + THROW_RANGEERROR("[from,to] interval out of bounds"); + } + if (c.isConstant()) return from; + SBasis dd = dot(c - p, dc); + std::vector<double> zeros = Geom::roots(dd); - double closest = from; - double min_dist_sq = L2sq(c(from) - p); - double distsq; - for ( unsigned int i = 0; i < zeros.size(); ++i ) - { - distsq = L2sq(c(zeros[i]) - p); - if ( min_dist_sq > L2sq(c(zeros[i]) - p) ) - { - closest = zeros[i]; - min_dist_sq = distsq; - } - } - if ( min_dist_sq > L2sq( c(to) - p ) ) - closest = to; - return closest; + double closest = from; + double min_dist_sq = L2sq(c(from) - p); + double distsq; + for ( unsigned int i = 0; i < zeros.size(); ++i ) + { + distsq = L2sq(c(zeros[i]) - p); + if ( min_dist_sq > L2sq(c(zeros[i]) - p) ) + { + closest = zeros[i]; + min_dist_sq = distsq; + } + } + if ( min_dist_sq > L2sq( c(to) - p ) ) + closest = to; + return closest; } @@ -89,54 +89,54 @@ double nearest_point( Point const& p, std::vector<double> all_nearest_points( Point const& p, - D2<SBasis> const& c, - D2<SBasis> const& dc, - double from, double to ) + D2<SBasis> const& c, + D2<SBasis> const& dc, + double from, double to ) { - std::swap(from, to); - if ( from > to ) std::swap(from, to); - if ( from < 0 || to > 1 ) - { - THROW_RANGEERROR("[from,to] interval out of bounds"); - } + std::swap(from, to); + if ( from > to ) std::swap(from, to); + if ( from < 0 || to > 1 ) + { + THROW_RANGEERROR("[from,to] interval out of bounds"); + } - std::vector<double> result; - if (c.isConstant()) - { - result.push_back(from); - return result; - } - SBasis dd = dot(c - p, dc); + std::vector<double> result; + if (c.isConstant()) + { + result.push_back(from); + return result; + } + SBasis dd = dot(c - p, dc); - std::vector<double> zeros = Geom::roots(dd); - std::vector<double> candidates; - candidates.push_back(from); - candidates.insert(candidates.end(), zeros.begin(), zeros.end()); - candidates.push_back(to); - std::vector<double> distsq; - distsq.reserve(candidates.size()); - for ( unsigned int i = 0; i < candidates.size(); ++i ) - { - distsq.push_back( L2sq(c(candidates[i]) - p) ); - } - unsigned int closest = 0; - double dsq = distsq[0]; - for ( unsigned int i = 1; i < candidates.size(); ++i ) - { - if ( dsq > distsq[i] ) - { - closest = i; - dsq = distsq[i]; - } - } - for ( unsigned int i = 0; i < candidates.size(); ++i ) - { - if( distsq[closest] == distsq[i] ) - { - result.push_back(candidates[i]); - } - } - return result; + std::vector<double> zeros = Geom::roots(dd); + std::vector<double> candidates; + candidates.push_back(from); + candidates.insert(candidates.end(), zeros.begin(), zeros.end()); + candidates.push_back(to); + std::vector<double> distsq; + distsq.reserve(candidates.size()); + for ( unsigned int i = 0; i < candidates.size(); ++i ) + { + distsq.push_back( L2sq(c(candidates[i]) - p) ); + } + unsigned int closest = 0; + double dsq = distsq[0]; + for ( unsigned int i = 1; i < candidates.size(); ++i ) + { + if ( dsq > distsq[i] ) + { + closest = i; + dsq = distsq[i]; + } + } + for ( unsigned int i = 0; i < candidates.size(); ++i ) + { + if( distsq[closest] == distsq[i] ) + { + result.push_back(candidates[i]); + } + } + return result; } @@ -145,141 +145,141 @@ all_nearest_points( Point const& p, double nearest_point( Point const& p, - Piecewise< D2<SBasis> > const& c, - double from, double to ) + Piecewise< D2<SBasis> > const& c, + double from, double to ) { - if ( from > to ) std::swap(from, to); - if ( from < c.cuts[0] || to > c.cuts[c.size()] ) - { - THROW_RANGEERROR("[from,to] interval out of bounds"); - } + if ( from > to ) std::swap(from, to); + if ( from < c.cuts[0] || to > c.cuts[c.size()] ) + { + THROW_RANGEERROR("[from,to] interval out of bounds"); + } - unsigned int si = c.segN(from); - unsigned int ei = c.segN(to); - if ( si == ei ) - { - double nearest= - nearest_point(p, c[si], c.segT(from, si), c.segT(to, si)); - return c.mapToDomain(nearest, si); - } - double t; - double nearest = nearest_point(p, c[si], c.segT(from, si)); - unsigned int ni = si; - double dsq; - double mindistsq = distanceSq(p, c[si](nearest)); - Rect bb; - for ( unsigned int i = si + 1; i < ei; ++i ) - { - bb = bounds_fast(c[i]); - dsq = distanceSq(p, bb); - if ( mindistsq <= dsq ) continue; - t = nearest_point(p, c[i]); - dsq = distanceSq(p, c[i](t)); - if ( mindistsq > dsq ) - { - nearest = t; - ni = i; - mindistsq = dsq; - } - } - bb = bounds_fast(c[ei]); - dsq = distanceSq(p, bb); - if ( mindistsq > dsq ) - { - t = nearest_point(p, c[ei], 0, c.segT(to, ei)); - dsq = distanceSq(p, c[ei](t)); - if ( mindistsq > dsq ) - { - nearest = t; - ni = ei; - } - } - return c.mapToDomain(nearest, ni); + unsigned int si = c.segN(from); + unsigned int ei = c.segN(to); + if ( si == ei ) + { + double nearest= + nearest_point(p, c[si], c.segT(from, si), c.segT(to, si)); + return c.mapToDomain(nearest, si); + } + double t; + double nearest = nearest_point(p, c[si], c.segT(from, si)); + unsigned int ni = si; + double dsq; + double mindistsq = distanceSq(p, c[si](nearest)); + Rect bb(Geom::Point(0,0),Geom::Point(0,0)); + for ( unsigned int i = si + 1; i < ei; ++i ) + { + bb = *bounds_fast(c[i]); + dsq = distanceSq(p, bb); + if ( mindistsq <= dsq ) continue; + t = nearest_point(p, c[i]); + dsq = distanceSq(p, c[i](t)); + if ( mindistsq > dsq ) + { + nearest = t; + ni = i; + mindistsq = dsq; + } + } + bb = *bounds_fast(c[ei]); + dsq = distanceSq(p, bb); + if ( mindistsq > dsq ) + { + t = nearest_point(p, c[ei], 0, c.segT(to, ei)); + dsq = distanceSq(p, c[ei](t)); + if ( mindistsq > dsq ) + { + nearest = t; + ni = ei; + } + } + return c.mapToDomain(nearest, ni); } std::vector<double> all_nearest_points( Point const& p, Piecewise< D2<SBasis> > const& c, - double from, double to ) + double from, double to ) { - if ( from > to ) std::swap(from, to); - if ( from < c.cuts[0] || to > c.cuts[c.size()] ) - { - THROW_RANGEERROR("[from,to] interval out of bounds"); - } + if ( from > to ) std::swap(from, to); + if ( from < c.cuts[0] || to > c.cuts[c.size()] ) + { + THROW_RANGEERROR("[from,to] interval out of bounds"); + } - unsigned int si = c.segN(from); - unsigned int ei = c.segN(to); - if ( si == ei ) - { - std::vector<double> all_nearest = - all_nearest_points(p, c[si], c.segT(from, si), c.segT(to, si)); - for ( unsigned int i = 0; i < all_nearest.size(); ++i ) - { - all_nearest[i] = c.mapToDomain(all_nearest[i], si); - } - return all_nearest; - } - std::vector<double> all_t; - std::vector< std::vector<double> > all_np; - all_np.push_back( all_nearest_points(p, c[si], c.segT(from, si)) ); - std::vector<unsigned int> ni; - ni.push_back(si); - double dsq; - double mindistsq = distanceSq( p, c[si](all_np.front().front()) ); - Rect bb; - for ( unsigned int i = si + 1; i < ei; ++i ) - { - bb = bounds_fast(c[i]); - dsq = distanceSq(p, bb); - if ( mindistsq < dsq ) continue; - all_t = all_nearest_points(p, c[i]); - dsq = distanceSq( p, c[i](all_t.front()) ); - if ( mindistsq > dsq ) - { - all_np.clear(); - all_np.push_back(all_t); - ni.clear(); - ni.push_back(i); - mindistsq = dsq; - } - else if ( mindistsq == dsq ) - { - all_np.push_back(all_t); - ni.push_back(i); - } - } - bb = bounds_fast(c[ei]); - dsq = distanceSq(p, bb); - if ( mindistsq >= dsq ) - { - all_t = all_nearest_points(p, c[ei], 0, c.segT(to, ei)); - dsq = distanceSq( p, c[ei](all_t.front()) ); - if ( mindistsq > dsq ) - { - for ( unsigned int i = 0; i < all_t.size(); ++i ) - { - all_t[i] = c.mapToDomain(all_t[i], ei); - } - return all_t; - } - else if ( mindistsq == dsq ) - { - all_np.push_back(all_t); - ni.push_back(ei); - } - } - std::vector<double> all_nearest; - for ( unsigned int i = 0; i < all_np.size(); ++i ) - { - for ( unsigned int j = 0; j < all_np[i].size(); ++j ) - { - all_nearest.push_back( c.mapToDomain(all_np[i][j], ni[i]) ); - } - } - all_nearest.erase(std::unique(all_nearest.begin(), all_nearest.end()), - all_nearest.end()); - return all_nearest; + unsigned int si = c.segN(from); + unsigned int ei = c.segN(to); + if ( si == ei ) + { + std::vector<double> all_nearest = + all_nearest_points(p, c[si], c.segT(from, si), c.segT(to, si)); + for ( unsigned int i = 0; i < all_nearest.size(); ++i ) + { + all_nearest[i] = c.mapToDomain(all_nearest[i], si); + } + return all_nearest; + } + std::vector<double> all_t; + std::vector< std::vector<double> > all_np; + all_np.push_back( all_nearest_points(p, c[si], c.segT(from, si)) ); + std::vector<unsigned int> ni; + ni.push_back(si); + double dsq; + double mindistsq = distanceSq( p, c[si](all_np.front().front()) ); + Rect bb(Geom::Point(0,0),Geom::Point(0,0)); + for ( unsigned int i = si + 1; i < ei; ++i ) + { + bb = *bounds_fast(c[i]); + dsq = distanceSq(p, bb); + if ( mindistsq < dsq ) continue; + all_t = all_nearest_points(p, c[i]); + dsq = distanceSq( p, c[i](all_t.front()) ); + if ( mindistsq > dsq ) + { + all_np.clear(); + all_np.push_back(all_t); + ni.clear(); + ni.push_back(i); + mindistsq = dsq; + } + else if ( mindistsq == dsq ) + { + all_np.push_back(all_t); + ni.push_back(i); + } + } + bb = *bounds_fast(c[ei]); + dsq = distanceSq(p, bb); + if ( mindistsq >= dsq ) + { + all_t = all_nearest_points(p, c[ei], 0, c.segT(to, ei)); + dsq = distanceSq( p, c[ei](all_t.front()) ); + if ( mindistsq > dsq ) + { + for ( unsigned int i = 0; i < all_t.size(); ++i ) + { + all_t[i] = c.mapToDomain(all_t[i], ei); + } + return all_t; + } + else if ( mindistsq == dsq ) + { + all_np.push_back(all_t); + ni.push_back(ei); + } + } + std::vector<double> all_nearest; + for ( unsigned int i = 0; i < all_np.size(); ++i ) + { + for ( unsigned int j = 0; j < all_np[i].size(); ++j ) + { + all_nearest.push_back( c.mapToDomain(all_np[i][j], ni[i]) ); + } + } + all_nearest.erase(std::unique(all_nearest.begin(), all_nearest.end()), + all_nearest.end()); + return all_nearest; } } // end namespace Geom diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index 715c67c23..5a4e76020 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -23,9 +23,9 @@ int winding(Path const &path, Point p) { Path::const_iterator start; for(Path::const_iterator iter = path.begin(); ; ++iter) { if(iter == path.end_closed()) { return 0; } - if(iter->initialPoint()[Y]!=p[Y]) { start = iter; break; } - if(iter->finalPoint()[Y]!=p[Y]) { start = iter; break; } - if(iter->boundsFast().height()!=0.){ start = iter; break; } + if(iter->initialPoint()[Y]!=p[Y]) { start = iter; break; } + if(iter->finalPoint()[Y]!=p[Y]) { start = iter; break; } + if(iter->boundsFast()->height()!=0.){ start = iter; break; } } int wind = 0; unsigned cnt = 0; @@ -36,7 +36,7 @@ int winding(Path const &path, Point p) { cnt++; if(cnt > path.size()) return wind; //some bug makes this required starting = false; - Rect bounds = iter->boundsFast(); + Rect bounds = *(iter->boundsFast()); Coord x = p[X], y = p[Y]; if(x > bounds.right() || !bounds[Y].contains(y)) continue; //ray doesn't intersect box @@ -70,7 +70,7 @@ int winding(Path const &path, Point p) { next++; for(; ; next++) { if(next == path.end_closed()) next = path.begin(); - Rect bnds = next->boundsFast(); + Rect bnds = *(next->boundsFast()); //TODO: X considerations if(bnds.height() > 0) { //It has diverged @@ -267,13 +267,13 @@ void pair_intersect(Curve const & A, double Al, double Ah, Curve const & B, double Bl, double Bh, Crossings &ret, unsigned depth=0) { // std::cout << depth << "(" << Al << ", " << Ah << ")\n"; - Rect Ar = A.boundsLocal(Interval(Al, Ah)); - if(Ar.isEmpty()) return; + OptRect Ar = A.boundsLocal(Interval(Al, Ah)); + if (!Ar) return; - Rect Br = B.boundsLocal(Interval(Bl, Bh)); - if(Br.isEmpty()) return; + OptRect Br = B.boundsLocal(Interval(Bl, Bh)); + if (!Br) return; - if(!Ar.intersects(Br)) return; + if(! Ar->intersects(*Br)) return; //Checks the general linearity of the function if((depth > 12)) { // || (A.boundsLocal(Interval(Al, Ah), 1).maxExtent() < 0.1 diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index c04d9d08d..136e6d481 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -43,21 +43,21 @@ using namespace Geom::PathInternal; namespace Geom { -Rect Path::boundsFast() const { - Rect bounds; +OptRect Path::boundsFast() const { + OptRect bounds; if (empty()) return bounds; bounds=front().boundsFast(); const_iterator iter = begin(); if ( iter != end() ) { - for ( ++iter; iter != end() ; ++iter ) { - bounds.unionWith(iter->boundsFast()); - } + for ( ++iter; iter != end() ; ++iter ) { + bounds.unionWith(iter->boundsFast()); + } } return bounds; } -Rect Path::boundsExact() const { - Rect bounds; +OptRect Path::boundsExact() const { + OptRect bounds; if (empty()) return bounds; bounds=front().boundsExact(); const_iterator iter = begin(); @@ -143,10 +143,10 @@ Path::allNearestPoints(Point const& _point, double from, double to) const double dsq; double mindistsq = distanceSq( _point, _path[si].pointAt( all_np.front().front() ) ); - Rect bb; + Rect bb(Geom::Point(0,0),Geom::Point(0,0)); for ( unsigned int i = si + 1; i < ei; ++i ) { - bb = _path[i].boundsFast(); + bb = *(_path[i].boundsFast()); dsq = distanceSq(_point, bb); if ( mindistsq < dsq ) continue; all_t = _path[i].allNearestPoints(_point); @@ -165,7 +165,7 @@ Path::allNearestPoints(Point const& _point, double from, double to) const ni.push_back(i); } } - bb = _path[ei].boundsFast(); + bb = *(_path[ei].boundsFast()); dsq = distanceSq(_point, bb); if ( mindistsq >= dsq ) { @@ -254,10 +254,10 @@ double Path::nearestPoint(Point const &_point, double from, double to, double *d unsigned int ni = si; double dsq; double mindistsq = distanceSq(_point, _path[si].pointAt(nearest)); - Rect bb; + Rect bb(Geom::Point(0,0),Geom::Point(0,0)); for ( unsigned int i = si + 1; i < ei; ++i ) { - bb = _path[i].boundsFast(); + bb = *(_path[i].boundsFast()); dsq = distanceSq(_point, bb); if ( mindistsq <= dsq ) continue; t = _path[i].nearestPoint(_point); @@ -269,7 +269,7 @@ double Path::nearestPoint(Point const &_point, double from, double to, double *d mindistsq = dsq; } } - bb = _path[ei].boundsFast(); + bb = *(_path[ei].boundsFast()); dsq = distanceSq(_point, bb); if ( mindistsq > dsq ) { diff --git a/src/2geom/path.h b/src/2geom/path.h index e02b749e7..b95a54eaa 100644 --- a/src/2geom/path.h +++ b/src/2geom/path.h @@ -259,8 +259,8 @@ public: bool closed() const { return closed_; } void close(bool closed=true) { closed_ = closed; } - Rect boundsFast() const; - Rect boundsExact() const; + OptRect boundsFast() const; + OptRect boundsExact() const; Piecewise<D2<SBasis> > toPwSb() const { Piecewise<D2<SBasis> > ret; @@ -566,8 +566,9 @@ public: } - /* + /** * It is important to note that the coordinates passed to appendNew should be finite! + * If one of the coordinates is infinite, 2geom will throw a ContinuityError exception. */ template <typename CurveType, typename A> diff --git a/src/2geom/pathvector.cpp b/src/2geom/pathvector.cpp index 39a00d8dc..790265c76 100644 --- a/src/2geom/pathvector.cpp +++ b/src/2geom/pathvector.cpp @@ -56,12 +56,11 @@ PathVector reverse_paths_and_order (PathVector const & path_in) return path_out; } -// FIXME: this function does not work for empty paths, because Rect cannot be initialized empty yet. check rect.h -Rect bounds_fast( PathVector const& pv ) +OptRect bounds_fast( PathVector const& pv ) { typedef PathVector::const_iterator const_iterator; - Rect bound; + OptRect bound; if (pv.empty()) return bound; bound = (pv.begin())->boundsFast(); @@ -72,12 +71,11 @@ Rect bounds_fast( PathVector const& pv ) return bound; } -// FIXME: this function does not work for empty paths, because Rect cannot be initialized empty yet. check rect.h -Rect bounds_exact( PathVector const& pv ) +OptRect bounds_exact( PathVector const& pv ) { typedef PathVector::const_iterator const_iterator; - Rect bound; + OptRect bound; if (pv.empty()) return bound; bound = (pv.begin())->boundsExact(); diff --git a/src/2geom/pathvector.h b/src/2geom/pathvector.h index 5df3ad00c..9efae7c73 100644 --- a/src/2geom/pathvector.h +++ b/src/2geom/pathvector.h @@ -102,8 +102,8 @@ Geom::Point finalPoint(PathVector const &path_in) PathVector reverse_paths_and_order (PathVector const & path_in); -Rect bounds_fast( PathVector const & pv ); -Rect bounds_exact( PathVector const & pv ); +OptRect bounds_fast( PathVector const & pv ); +OptRect bounds_exact( PathVector const & pv ); struct PathVectorPosition { // pathvector[path_nr].pointAt(t) is the position diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h index ec3ba26ce..bbd1f054a 100644 --- a/src/2geom/piecewise.h +++ b/src/2geom/piecewise.h @@ -80,6 +80,8 @@ class Piecewise { push_cut(1.); } + unsigned input_dim(){return 1;} + typedef typename T::output_type output_type; explicit Piecewise(const output_type & v) { @@ -198,14 +200,18 @@ class Piecewise { //Transforms the domain into another interval inline void setDomain(Interval dom) { if(empty()) return; + /* dom can not be empty if(dom.isEmpty()) { cuts.clear(); segs.clear(); return; - } + }*/ double cf = cuts.front(); double o = dom.min() - cf, s = dom.extent() / (cuts.back() - cf); for(unsigned i = 0; i <= size(); i++) cuts[i] = (cuts[i] - cf) * s + o; + //fix floating point precision errors. + cuts[0] = dom.min(); + cuts[size()] = dom.max(); } //Concatenates this Piecewise function with another, offseting time of the other to match the end. @@ -227,15 +233,15 @@ class Piecewise { inline void continuousConcat(const Piecewise<T> &other) { boost::function_requires<AddableConcept<typename T::output_type> >(); if(other.empty()) return; - typename T::output_type y = segs.back().at1() - other.segs.front().at0(); if(empty()) { for(unsigned i = 0; i < other.size(); i++) - push_seg(other[i] + y); + push_seg(other[i]); cuts = other.cuts; return; } + typename T::output_type y = segs.back().at1() - other.segs.front().at0(); double t = cuts.back() - other.cuts.front(); for(unsigned i = 0; i < other.size(); i++) push(other[i] + y, other.cuts[i + 1] + t); @@ -278,11 +284,12 @@ inline typename FragmentConcept<T>::BoundsType bounds_exact(const Piecewise<T> & } template<typename T> -inline typename FragmentConcept<T>::BoundsType bounds_local(const Piecewise<T> &f, const Interval &m) { +inline typename FragmentConcept<T>::BoundsType bounds_local(const Piecewise<T> &f, const OptInterval &_m) { boost::function_requires<FragmentConcept<T> >(); - if(f.empty()) return typename FragmentConcept<T>::BoundsType(); - if(m.isEmpty()) return typename FragmentConcept<T>::BoundsType(f(m.min())); + if(f.empty() || !_m) return typename FragmentConcept<T>::BoundsType(); + Interval const &m = *_m; + if(m.isSingular()) return typename FragmentConcept<T>::BoundsType(f(m.min())); unsigned fi = f.segN(m.min()), ti = f.segN(m.max()); double ft = f.segT(m.min(), fi), tt = f.segT(m.max(), ti); @@ -640,7 +647,7 @@ Piecewise<T> compose(Piecewise<T> const &f, SBasis const &g){ } //first check bounds... - Interval bs = bounds_fast(g); + Interval bs = *bounds_fast(g); if (f.cuts.front() > bs.max() || bs.min() > f.cuts.back()){ int idx = (bs.max() < f.cuts[1]) ? 0 : f.cuts.size()-2; double t0 = f.cuts[idx], width = f.cuts[idx+1] - t0; diff --git a/src/2geom/point.h b/src/2geom/point.h index e6e74242d..d89b53f83 100644 --- a/src/2geom/point.h +++ b/src/2geom/point.h @@ -9,6 +9,7 @@ #include <iostream> #include <2geom/coord.h> +#include <2geom/isnan.h> #include <2geom/utils.h> namespace Geom { @@ -22,6 +23,7 @@ class Point { Coord _pt[2]; public: + /// The default constructor creates an Point(0,0) DO NOT RELY ON THIS, BEST NOT TO USE THIS CONSTRUCTOR inline Point() { _pt[X] = _pt[Y] = 0; } @@ -81,6 +83,13 @@ class Point { void normalize(); + inline bool isFinite() const { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + if(!IS_FINITE(_pt[i])) return false; + } + return true; + } + inline Point operator+(Point const &o) const { return Point(_pt[X] + o._pt[X], _pt[Y] + o._pt[Y]); } diff --git a/src/2geom/rect.h b/src/2geom/rect.h index 563c8a058..fb42ff92d 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -48,6 +48,7 @@ namespace Geom { /** D2<Interval> specialization to Rect */ typedef D2<Interval> Rect; +class OptRect; Rect unify(const Rect &, const Rect &); /** @@ -60,10 +61,12 @@ class D2<Interval> { private: Interval f[2]; public: - /* The default constructor creates an empty rect, constructed of two empty Intervals. (users rely on this!) + /** Best not to use this constructor, do not rely on what it initializes the object to. + *The default constructor creates a rect of default intervals. */ D2<Interval>() { f[X] = f[Y] = Interval(); } + public: D2<Interval>(Interval const &a, Interval const &b) { f[X] = a; f[Y] = b; @@ -105,14 +108,20 @@ class D2<Interval> { inline Point midpoint() const { return Point(f[X].middle(), f[Y].middle()); } /** - * Compute the area of this rectangle. Note that a zero area rectangle is not necessarily empty - just as the interval [0,0] contains one point, the rectangle [0,0] x [0,0] contains 1 point and no area. + * \brief Compute the area of this rectangle. + * + * Note that a zero area rectangle is not empty - just as the interval [0,0] contains one point, the rectangle [0,0] x [0,0] contains 1 point and no area. + * \retval For a valid return value, the rect must be tested for emptyness first. */ inline double area() const { return f[X].extent() * f[Y].extent(); } + inline bool hasZeroArea(double eps = EPSILON) const { return (area() <= eps); } + inline double maxExtent() const { return std::max(f[X].extent(), f[Y].extent()); } + inline double minExtent() const { return std::min(f[X].extent(), f[Y].extent()); } - inline bool isEmpty() const { - return f[X].isEmpty() || f[Y].isEmpty(); - } +// inline bool isEmpty() const { +// return f[X].isEmpty() || f[Y].isEmpty(); +// } inline bool intersects(Rect const &r) const { return f[X].intersects(r[X]) && f[Y].intersects(r[Y]); } @@ -129,40 +138,20 @@ class D2<Interval> { inline void unionWith(Rect const &b) { f[X].unionWith(b[X]); f[Y].unionWith(b[Y]); } + void unionWith(OptRect const &b); - inline void expandBy(double amnt) { + inline void expandBy(double amnt) { f[X].expandBy(amnt); f[Y].expandBy(amnt); } inline void expandBy(Point const p) { f[X].expandBy(p[X]); f[Y].expandBy(p[Y]); } - - /** Transforms the rect by m. Note that it gives correct results only for scales and translates, - in the case of rotations, the area of the rect will grow as it cannot rotate. */ - inline Rect operator*(Matrix const m) const { - return unify(Rect(corner(0) * m, corner(2) * m), - Rect(corner(1) * m, corner(3) * m)); - } }; inline Rect unify(Rect const & a, Rect const & b) { return Rect(unify(a[X], b[X]), unify(a[Y], b[Y])); } -/** - * Returns the smallest rectangle that encloses both rectangles. - * An empty argument is assumed to be an empty rectangle - */ -inline boost::optional<Rect> unify(boost::optional<Rect> const & a, boost::optional<Rect> const & b) { - if (!a) { - return b; - } else if (!b) { - return a; - } else { - return unify(*a, *b); - } -} - inline Rect union_list(std::vector<Rect> const &r) { if(r.empty()) return Rect(Interval(0,0), Interval(0,0)); Rect ret = r[0]; @@ -171,12 +160,6 @@ inline Rect union_list(std::vector<Rect> const &r) { return ret; } -inline boost::optional<Rect> intersect(Rect const & a, Rect const & b) { - boost::optional<Interval> x = intersect(a[X], b[X]); - boost::optional<Interval> y = intersect(a[Y], b[Y]); - return x && y ? boost::optional<Rect>(Rect(*x, *y)) : boost::optional<Rect>(); -} - inline double distanceSq( Point const& p, Rect const& rect ) { @@ -209,6 +192,70 @@ double distance( Point const& p, Rect const& rect ) return std::sqrt(distanceSq(p, rect)); } +/** + * The OptRect class can represent and empty Rect and non-empty Rects. + * If OptRect is not empty, it means that both X and Y intervals are not empty. + * + */ +class OptRect : public boost::optional<Rect> { +public: + OptRect() : boost::optional<Rect>() {}; + OptRect(Rect const &a) : boost::optional<Rect>(a) {}; + + /** + * Creates an empty OptRect when one of the argument intervals is empty. + */ + OptRect(OptInterval const &x_int, OptInterval const &y_int) { + if (x_int && y_int) { + *this = Rect(*x_int, *y_int); + } + // else, stay empty. + } + + /** + * Check whether this OptRect is empty or not. + */ + inline bool isEmpty() { return (*this == false); }; + + /** + * If \c this is empty, copy argument \c b. Otherwise, union with it (and do nothing when \c b is empty) + */ + inline void unionWith(OptRect const &b) { + if (b) { + if (*this) { // check that we are not empty + (**this)[X].unionWith((*b)[X]); + (**this)[Y].unionWith((*b)[Y]); + } else { + *this = b; + } + } + } +}; + + +/** + * Returns the smallest rectangle that encloses both rectangles. + * An empty argument is assumed to be an empty rectangle + */ +inline OptRect unify(OptRect const & a, OptRect const & b) { + if (!a) { + return b; + } else if (!b) { + return a; + } else { + return unify(*a, *b); + } +} + +inline OptRect intersect(Rect const & a, Rect const & b) { + return OptRect(intersect(a[X], b[X]), intersect(a[Y], b[Y])); +} + +inline void Rect::unionWith(OptRect const &b) { + if (b) { + unionWith(*b); + } +} } // end namespace Geom diff --git a/src/2geom/region.h b/src/2geom/region.h index 7b2f5763d..fe2517e23 100644 --- a/src/2geom/region.h +++ b/src/2geom/region.h @@ -48,14 +48,14 @@ class Region { friend Shape shape_boolean(bool rev, Shape const & a, Shape const & b, CrossingSet const & crs); Path boundary; - mutable boost::optional<Rect> box; + mutable OptRect box; bool fill; public: Region() : fill(true) {} explicit Region(Path const &p) : boundary(p) { fill = path_direction(p); } Region(Path const &p, bool dir) : boundary(p), fill(dir) {} - Region(Path const &p, boost::optional<Rect> const &b) : boundary(p), box(b) { fill = path_direction(p); } - Region(Path const &p, boost::optional<Rect> const &b, bool dir) : boundary(p), box(b), fill(dir) {} + Region(Path const &p, OptRect const &b) : boundary(p), box(b) { fill = path_direction(p); } + Region(Path const &p, OptRect const &b, bool dir) : boundary(p), box(b), fill(dir) {} unsigned size() const { return boundary.size(); } @@ -65,7 +65,7 @@ class Region { operator Path() const { return boundary; } Rect boundsFast() const { - if(!box) box = boost::optional<Rect>(boundary.boundsFast()); + if(!box) box = boundary.boundsFast(); /// \todo this doesn't look right at all... return *box; } diff --git a/src/2geom/sbasis-2d.cpp b/src/2geom/sbasis-2d.cpp index 9566e0a19..e3a407094 100644 --- a/src/2geom/sbasis-2d.cpp +++ b/src/2geom/sbasis-2d.cpp @@ -173,7 +173,7 @@ sb2d_cubic_solve(SBasis2d const &f, Geom::Point const &A, Geom::Point const &B){ double error = -1; unsigned best = 0; for (unsigned i=0; i<candidates.size(); i++){ - Interval bounds = bounds_fast(compose(f,candidates[i])); + Interval bounds = *bounds_fast(compose(f,candidates[i])); double new_error = (fabs(bounds.max())>fabs(bounds.min()) ? fabs(bounds.max()) : fabs(bounds.min()) ); if ( new_error < error || error < 0 ){ error = new_error; diff --git a/src/2geom/sbasis-curve.h b/src/2geom/sbasis-curve.h index e11919401..b45e63eb8 100644 --- a/src/2geom/sbasis-curve.h +++ b/src/2geom/sbasis-curve.h @@ -68,9 +68,9 @@ public: void setInitial(Point v) { for(unsigned d = 0; d < 2; d++) { inner[d][0][0] = v[d]; } } void setFinal(Point v) { for(unsigned d = 0; d < 2; d++) { inner[d][0][1] = v[d]; } } - Rect boundsFast() const { return bounds_fast(inner); } - Rect boundsExact() const { return bounds_exact(inner); } - Rect boundsLocal(Interval i, unsigned deg) const { return bounds_local(inner, i, deg); } + virtual OptRect boundsFast() const { return bounds_fast(inner); } + virtual OptRect boundsExact() const { return bounds_exact(inner); } + virtual OptRect boundsLocal(OptInterval i, unsigned deg) const { return bounds_local(inner, i, deg); } std::vector<double> roots(double v, Dim2 d) const { return Geom::roots(inner[d] - v); } diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index f0170ec6b..96a5ed0ce 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -528,7 +528,7 @@ unsigned Geom::centroid(Piecewise<D2<SBasis> > const &p, Point& centroid, double * Below are basic functions dedicated to solving this assuming a0 and a1 !=0. */ -static Interval +static OptInterval find_bounds_for_lambda0(double aa0,double aa1,double cc0,double cc1, int insist_on_speeds_signs){ @@ -541,7 +541,7 @@ find_bounds_for_lambda0(double aa0,double aa1,double cc0,double cc1, double c = (c0<c1 ? c0 : c1); double delta = 1-4*a*c; if ( delta < 0 ) - return Interval();//return empty interval + return OptInterval();//return empty interval double lambda_max = (1+std::sqrt(delta))/2/a; result = Interval(c,lambda_max); @@ -549,9 +549,10 @@ find_bounds_for_lambda0(double aa0,double aa1,double cc0,double cc1, result *= -1; if (insist_on_speeds_signs == 1){ if (result.max() < 0)//Caution: setMin with max<new min... - return Interval();//return empty interval + return OptInterval();//return empty interval result.setMin(0); } + result = Interval(result.min()-.1,result.max()+.1);//just in case all our approx. were exact... return result; } @@ -565,13 +566,13 @@ solve_lambda0(double a0,double a1,double c0,double c1, p.push_back(Linear( -a1*a0*(a0+2*c0), -a1*a0*(3*a0+2*c0) )); p.push_back(Linear( a1*a0*a0 )); - Interval domain = find_bounds_for_lambda0(a0,a1,c0,c1,insist_on_speeds_signs); - if ( domain.isEmpty() ) + OptInterval domain = find_bounds_for_lambda0(a0,a1,c0,c1,insist_on_speeds_signs); + if ( !domain ) return std::vector<double>(); - p = compose(p,Linear(domain.min(),domain.max())); + p = compose(p,Linear(domain->min(),domain->max())); std::vector<double>rts = roots(p); for (unsigned i=0; i<rts.size(); i++){ - rts[i] = domain.min()+rts[i]*domain.extent(); + rts[i] = domain->min() + rts[i] * domain->extent(); } return rts; } diff --git a/src/2geom/sbasis-math.cpp b/src/2geom/sbasis-math.cpp index 1d179a563..e08023e84 100644 --- a/src/2geom/sbasis-math.cpp +++ b/src/2geom/sbasis-math.cpp @@ -41,6 +41,7 @@ namespace Geom { +#include <2geom/d2-sbasis.h> #include <stdio.h> #include <math.h> @@ -327,18 +328,44 @@ Piecewise<SBasis> reciprocalOnDomain(Interval range, double tol){ } Piecewise<SBasis> reciprocal(SBasis const &f, double tol, int order){ - Piecewise<SBasis> reciprocal_fn=reciprocalOnDomain(bounds_fast(f), tol); + Piecewise<SBasis> reciprocal_fn=reciprocalOnDomain(*bounds_fast(f), tol); Piecewise<SBasis> result=compose(reciprocal_fn,f); truncateResult(result,order); return(result); } Piecewise<SBasis> reciprocal(Piecewise<SBasis> const &f, double tol, int order){ - Piecewise<SBasis> reciprocal_fn=reciprocalOnDomain(bounds_fast(f), tol); + Piecewise<SBasis> reciprocal_fn=reciprocalOnDomain(*bounds_fast(f), tol); Piecewise<SBasis> result=compose(reciprocal_fn,f); truncateResult(result,order); return(result); } +/** + * \brief Retruns a Piecewise SBasis with prescribed values at prescribed times. + * + * \param times: vector of times at which the values are given. Should be sorted in increasing order. + * \param values: vector of prescribed values. Should have the same size as times and be sorted accordingly. + * \param smoothness: (defaults to 1) regularity class of the result: 0=piecewise linear, 1=continuous derivative, etc... + */ +Piecewise<SBasis> interpolate(std::vector<double> times, std::vector<double> values, unsigned smoothness){ + assert ( values.size() == times.size() ); + if ( values.size() == 0 ) return Piecewise<SBasis>(); + if ( values.size() == 1 ) return Piecewise<SBasis>(values[0]);//what about time?? + + SBasis sk = shift(Linear(1.),smoothness); + SBasis bump_in = integral(sk); + bump_in -= bump_in.at0(); + bump_in /= bump_in.at1(); + SBasis bump_out = reverse( bump_in ); + + Piecewise<SBasis> result; + result.cuts.push_back(times[0]); + for (unsigned i = 0; i<values.size()-1; i++){ + result.push(bump_out*values[i]+bump_in*values[i+1],times[i+1]); + } + return result; +} + } /* diff --git a/src/2geom/sbasis-math.h b/src/2geom/sbasis-math.h index 053c2d285..49ad965d4 100644 --- a/src/2geom/sbasis-math.h +++ b/src/2geom/sbasis-math.h @@ -42,6 +42,7 @@ #include <2geom/sbasis.h> #include <2geom/piecewise.h> +#include <2geom/d2.h> namespace Geom{ //-|x|--------------------------------------------------------------- @@ -81,6 +82,8 @@ Piecewise<SBasis> reciprocalOnDomain(Interval range, double tol=1e-3); Piecewise<SBasis> reciprocal( SBasis const &f, double tol=1e-3, int order=3); Piecewise<SBasis> reciprocal(Piecewise<SBasis>const &f, double tol=1e-3, int order=3); +//--interpolate------------------------------------------------------------ +Piecewise<SBasis> interpolate( std::vector<double> times, std::vector<double> values, unsigned smoothness = 1); } #endif //SEEN_GEOM_PW_SB_CALCULUS_H diff --git a/src/2geom/sbasis-roots.cpp b/src/2geom/sbasis-roots.cpp index 2eb1e4cbb..5249053fa 100644 --- a/src/2geom/sbasis-roots.cpp +++ b/src/2geom/sbasis-roots.cpp @@ -57,7 +57,19 @@ namespace Geom{ \returns inteval */ -Interval bounds_exact(SBasis const &a) { + +#ifdef USE_SBASIS_OF +OptInterval bounds_exact(SBasisOf<double> const &a) { + Interval result = Interval(a.at0(), a.at1()); + SBasisOf<double> df = derivative(a); + vector<double>extrema = roots(df); + for (unsigned i=0; i<extrema.size(); i++){ + result.extendTo(a(extrema[i])); + } + return result; +} +#else +OptInterval bounds_exact(SBasis const &a) { Interval result = Interval(a.at0(), a.at1()); SBasis df = derivative(a); vector<double>extrema = roots(df); @@ -66,6 +78,7 @@ Interval bounds_exact(SBasis const &a) { } return result; } +#endif /** Find a small interval that bounds a \param a sbasis function @@ -73,7 +86,11 @@ Interval bounds_exact(SBasis const &a) { */ // I have no idea how this works, some clever bounding argument by jfb. -Interval bounds_fast(const SBasis &sb, int order) { +#ifdef USE_SBASIS_OF +OptInterval bounds_fast(const SBasisOf<double> &sb, int order) { +#else +OptInterval bounds_fast(const SBasis &sb, int order) { +#endif Interval res(0,0); // an empty sbasis is 0. for(int j = sb.size()-1; j>=order; j--) { @@ -105,11 +122,15 @@ Interval bounds_fast(const SBasis &sb, int order) { \param sb sbasis function \param i domain interval \param order number of terms - \returns inteval + \return interval */ -Interval bounds_local(const SBasis &sb, const Interval &i, int order) { - double t0=i.min(), t1=i.max(), lo=0., hi=0.; +#ifdef USE_SBASIS_OF +OptInterval bounds_local(const SBasisOf<double> &sb, const OptInterval &i, int order) { +#else +OptInterval bounds_local(const SBasis &sb, const OptInterval &i, int order) { +#endif + double t0=i->min(), t1=i->max(), lo=0., hi=0.; for(int j = sb.size()-1; j>=order; j--) { double a=sb[j][0]; double b=sb[j][1]; @@ -154,8 +175,13 @@ static int upper_level(vector<double> const &levels,double x,double tol=0.){ return(upper_bound(levels.begin(),levels.end(),x-tol)-levels.begin()); } +#ifdef USE_SBASIS_OF +static void multi_roots_internal(SBasis const &f, + SBasis const &df, +#else static void multi_roots_internal(SBasis const &f, SBasis const &df, +#endif std::vector<double> const &levels, std::vector<std::vector<double> > &roots, double htol, @@ -209,7 +235,7 @@ static void multi_roots_internal(SBasis const &f, int idxa=upper_level(levels,fa,vtol); int idxb=upper_level(levels,fb,vtol); - Interval bs = bounds_local(df,Interval(a,b)); + Interval bs = *bounds_local(df,Interval(a,b)); //first times when a level (higher or lower) can be reached from a or b. double ta_hi,tb_hi,ta_lo,tb_lo; @@ -306,8 +332,8 @@ std::vector<std::vector<double> > multi_roots(SBasis const &f, void subdiv_sbasis(SBasis const & s, std::vector<double> & roots, double left, double right) { - Interval bs = bounds_fast(s); - if(bs.min() > 0 || bs.max() < 0) + OptInterval bs = bounds_fast(s); + if(!bs || bs->min() > 0 || bs->max() < 0) return; // no roots here if(s.tailError(1) < 1e-7) { double t = s[0][0] / (s[0][0] - s[0][1]); diff --git a/src/2geom/sbasis.cpp b/src/2geom/sbasis.cpp index 2619da594..0bd672c15 100644 --- a/src/2geom/sbasis.cpp +++ b/src/2geom/sbasis.cpp @@ -43,7 +43,7 @@ namespace Geom{ \returns the largest possible error this truncation could give */ double SBasis::tailError(unsigned tail) const { - Interval bs = bounds_fast(*this, tail); + Interval bs = *bounds_fast(*this, tail); return std::max(fabs(bs.min()),fabs(bs.max())); } @@ -212,7 +212,7 @@ SBasis shift(SBasis const &a, int sh) { */ SBasis shift(Linear const &a, int sh) { SBasis c; - if(sh > 0) { + if(sh >= 0) { c.insert(c.begin(), sh, Linear(0,0)); c.push_back(a); } diff --git a/src/2geom/sbasis.h b/src/2geom/sbasis.h index 72bf422e7..f2681a722 100644 --- a/src/2geom/sbasis.h +++ b/src/2geom/sbasis.h @@ -43,7 +43,14 @@ #include <2geom/utils.h> #include <2geom/exception.h> -namespace Geom { + +#ifdef USE_SBASIS_OF + +#include "sbasis-of.h" + +#else + +namespace Geom{ /*** An empty SBasis is identically 0. */ class SBasis : public std::vector<Linear>{ @@ -135,9 +142,9 @@ private: inline SBasis Linear::toSBasis() const { return SBasis(*this); } //implemented in sbasis-roots.cpp -Interval bounds_exact(SBasis const &a); -Interval bounds_fast(SBasis const &a, int order = 0); -Interval bounds_local(SBasis const &a, const Interval &t, int order = 0); +OptInterval bounds_exact(SBasis const &a); +OptInterval bounds_fast(SBasis const &a, int order = 0); +OptInterval bounds_local(SBasis const &a, const OptInterval &t, int order = 0); /** Returns a function which reverses the domain of a. \param a sbasis function @@ -325,6 +332,7 @@ std::vector<std::vector<double> > multi_roots(SBasis const &f, double b=1); } +#endif /* Local Variables: diff --git a/src/2geom/shape.cpp b/src/2geom/shape.cpp index 814c6c68c..64abf48ff 100644 --- a/src/2geom/shape.cpp +++ b/src/2geom/shape.cpp @@ -349,7 +349,7 @@ void crossing_dual(unsigned &i, unsigned &j, CrossingSet const & crs) { //locate a crossing on the outside, by casting a ray through the middle of the bbox void outer_crossing(unsigned &ix, unsigned &jx, bool & dir, std::vector<Path> const & ps, CrossingSet const & crs) { - Rect bounds = ps[ix].boundsFast(); + Rect bounds = *(ps[ix].boundsFast()); double ry = bounds[Y].middle(); double max_val = bounds.left(), max_t = 0; ix = ps.size(); diff --git a/src/2geom/svg-elliptical-arc.cpp b/src/2geom/svg-elliptical-arc.cpp index 23645fe11..42c787eca 100644 --- a/src/2geom/svg-elliptical-arc.cpp +++ b/src/2geom/svg-elliptical-arc.cpp @@ -47,7 +47,7 @@ namespace Geom { -Rect SVGEllipticalArc::boundsExact() const +OptRect SVGEllipticalArc::boundsExact() const { if (isDegenerate() && is_svg_compliant()) return chord().boundsExact(); diff --git a/src/2geom/svg-elliptical-arc.h b/src/2geom/svg-elliptical-arc.h index 1d6d2d74d..92ec51b49 100644 --- a/src/2geom/svg-elliptical-arc.h +++ b/src/2geom/svg-elliptical-arc.h @@ -200,15 +200,15 @@ class SVGEllipticalArc : public Curve return m_svg_compliant; } - Rect boundsFast() const + virtual OptRect boundsFast() const { return boundsExact(); } - Rect boundsExact() const; + virtual OptRect boundsExact() const; // TODO: native implementation of the following methods - Rect boundsLocal(Interval i, unsigned int deg) const + virtual OptRect boundsLocal(OptInterval i, unsigned int deg) const { if (isDegenerate() && is_svg_compliant()) return chord().boundsLocal(i, deg); diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index 2f26870a5..071b171b3 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -38,6 +38,7 @@ #include <2geom/point.h> #include <2geom/svg-path-parser.h> +#include <2geom/angle.h> namespace Geom { @@ -139,7 +140,7 @@ private: }; -#line 143 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" +#line 144 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" static const char _svg_path_actions[] = { 0, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 15, 1, @@ -1144,7 +1145,7 @@ static const int svg_path_first_final = 270; static const int svg_path_en_main = 1; -#line 143 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 144 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" void Parser::parse(char const *str) @@ -1157,12 +1158,12 @@ throw(SVGPathParseError) _reset(); -#line 1161 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1162 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" { cs = svg_path_start; } -#line 1166 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1167 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" { int _klen; unsigned int _trans; @@ -1235,13 +1236,13 @@ _match: switch ( *_acts++ ) { case 0: -#line 155 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 156 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { start = p; } break; case 1: -#line 159 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 160 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { char const *end=p; std::string buf(start, end); @@ -1250,55 +1251,55 @@ _match: } break; case 2: -#line 166 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 167 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _push(1.0); } break; case 3: -#line 170 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 171 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _push(0.0); } break; case 4: -#line 174 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 175 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = true; } break; case 5: -#line 178 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 179 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = false; } break; case 6: -#line 182 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 183 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _moveTo(_pop_point()); } break; case 7: -#line 186 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 187 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _lineTo(_pop_point()); } break; case 8: -#line 190 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 191 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _hlineTo(Point(_pop_coord(X), _current[Y])); } break; case 9: -#line 194 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 195 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _vlineTo(Point(_current[X], _pop_coord(Y))); } break; case 10: -#line 198 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 199 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1307,7 +1308,7 @@ _match: } break; case 11: -#line 205 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 206 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1315,7 +1316,7 @@ _match: } break; case 12: -#line 211 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 212 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c = _pop_point(); @@ -1323,14 +1324,14 @@ _match: } break; case 13: -#line 217 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 218 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); _quadTo(_quad_tangent, p); } break; case 14: -#line 222 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 223 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { Point point = _pop_point(); bool sweep = _pop_flag(); @@ -1343,16 +1344,16 @@ _match: } break; case 15: -#line 233 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 234 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" { _closePath(); } break; case 16: -#line 369 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 370 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" {goto _out;} break; -#line 1356 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1357 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.cpp" } } @@ -1363,7 +1364,7 @@ _again: goto _resume; _out: {} } -#line 379 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" +#line 380 "/home/njh/svn/lib2geom/src/2geom/svg-path-parser.rl" if ( cs < svg_path_first_final ) { diff --git a/src/2geom/sweep.cpp b/src/2geom/sweep.cpp index 227c822bd..53b953255 100644 --- a/src/2geom/sweep.cpp +++ b/src/2geom/sweep.cpp @@ -9,10 +9,8 @@ std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> rs) { std::vector<std::vector<unsigned> > pairs(rs.size()); for(unsigned i = 0; i < rs.size(); i++) { - if(!rs[i].isEmpty()) { - events.push_back(Event(rs[i].left(), i, false)); - events.push_back(Event(rs[i].right(), i, true)); - } + events.push_back(Event(rs[i].left(), i, false)); + events.push_back(Event(rs[i].right(), i, true)); } std::sort(events.begin(), events.end()); @@ -48,10 +46,8 @@ std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> a, std::vecto events[n].reserve(sz*2); for(unsigned i = 0; i < sz; i++) { Rect r = n ? b[i] : a[i]; - if(!r.isEmpty()) { - events[n].push_back(Event(r.left(), i, false)); - events[n].push_back(Event(r.right(), i, true)); - } + events[n].push_back(Event(r.left(), i, false)); + events[n].push_back(Event(r.right(), i, true)); } std::sort(events[n].begin(), events[n].end()); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a84909382..5e4b41d01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -204,10 +204,6 @@ snapped-line.cpp snapped-point.cpp snapper.cpp star-context.cpp -streams-gzip.cpp -streams-handles.cpp -streams-jar.cpp -streams-zlib.cpp style.cpp #style-test.cpp svg-view.cpp diff --git a/src/Doxyfile b/src/Doxyfile deleted file mode 100644 index 42fbee2c2..000000000 --- a/src/Doxyfile +++ /dev/null @@ -1,62 +0,0 @@ -# Doxyfile: default configuration for `doxygen'. - -# We used to explicitly list inputs (for faster doxygen runs), but -# switched to recursive scan because we have a large number of inputs -# and almost everybody forgot to update the list to reflect latest changes. -FILE_PATTERNS = *.cpp *.h -RECURSIVE = yes -EXCLUDE_PATTERNS = sp-skeleton.* -# Input used to be generated with the command -# find -name '*.cpp' -o -name '*.h'|xargs grep -l '\\file'|sort|sed 's,^./, ,;s,$, \\,' -# (and remove the non source files sp-skeleton.*). -#INPUT = \ -# application/application.cpp \ -# (file listing was here...) - - -# Uncomment this to treat undocumented things as if they had an empty -# documentation string; comment it out to suppress all undocumented things from -# the output. -# Leaving it uncommented allows using doxygen output as the primary information -# source about a class (without needing to look at the source code to look for -# undocumented things). -# OTOH, you may find it annoying to have reems of relatively unhelpful -# information: commenting it out gives more compact display of the helpful -# bits. -# I'm commenting it out for now to facilitate checking existing doc comments -# for doxygen correctness. -#EXTRACT_ALL = yes - -# I'll disable this for the moment, to reduce the number of files in the output. -SOURCE_BROWSER = no - -# Keep the output out of the src directory so that it doesn't get in the way of -# `rgrep'. -OUTPUT_DIRECTORY = ../doxygen - -# In absence of explicit `\brief', treat the first "sentence" as the brief part -# and the rest as detail. (With explicit `\brief', the first _paragraph_ is -# considered the brief part.) -# -# It's unclear whether programmers should deliberately use this facility. -# Advantage: Less clutter. -# Disadvantage: Absence of `\brief' may indicate that the comment was written -# by someone unfamiliar with doxygen and not giving thought to what the brief -# description should be. Using explicit `\brief' may facilitate checking -# non-\briefed comments for doxygen correctness. -# OTOH, using `\brief' may be parrot-like: it doesn't necessarily indicate -# doxygen familiarity. -JAVADOC_AUTOBRIEF = yes - -WARN_IF_UNDOCUMENTED = yes - -GENERATE_TODOLIST = yes - -GENERATE_BUGLIST = yes - -REFERENCED_BY_RELATION = yes - -EXTRACT_STATIC = yes - -WARN_LOGFILE = doxygen-log - diff --git a/src/Makefile.am b/src/Makefile.am index 0726b7228..c6b58bce8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,7 @@ include extension/Makefile_insert include extension/implementation/Makefile_insert include extension/internal/Makefile_insert include extension/script/Makefile_insert +include filters/Makefile_insert include helper/Makefile_insert include inkjar/Makefile_insert include io/Makefile_insert @@ -87,6 +88,7 @@ noinst_LIBRARIES = \ extension/internal/libinternal.a \ extension/libextension.a \ extension/script/libscript.a \ + filters/libfilters.a \ bind/libbind.a \ helper/libspchelp.a \ io/libio.a \ @@ -146,6 +148,7 @@ EXTRA_DIST = \ extension/internal/makefile.in \ extension/makefile.in \ extension/script/makefile.in \ + filters/makefile.in \ helper/makefile.in \ inkjar/makefile.in \ io/makefile.in \ diff --git a/src/Makefile_insert b/src/Makefile_insert index 8244996c8..4bef3dc56 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -166,41 +166,6 @@ libinkpre_a_SOURCES = \ sp-defs.cpp sp-defs.h \ sp-desc.cpp sp-desc.h \ sp-ellipse.cpp sp-ellipse.h \ - sp-feblend.cpp sp-feblend.h \ - sp-feblend-fns.h \ - sp-fecolormatrix.cpp sp-fecolormatrix.h \ - sp-fecolormatrix-fns.h \ - sp-fecomponenttransfer.cpp sp-fecomponenttransfer.h \ - sp-fecomponenttransfer-funcnode.cpp sp-fecomponenttransfer-funcnode.h \ - sp-fecomponenttransfer-fns.h \ - sp-fecomposite.cpp sp-fecomposite.h \ - sp-fecomposite-fns.h \ - sp-feconvolvematrix.cpp sp-feconvolvematrix.h \ - sp-feconvolvematrix-fns.h \ - sp-fediffuselighting.cpp sp-fediffuselighting.h \ - sp-fediffuselighting-fns.h \ - sp-fedisplacementmap.cpp sp-fedisplacementmap.h \ - sp-fedisplacementmap-fns.h \ - sp-fedistantlight.cpp sp-fedistantlight.h \ - sp-feflood.cpp sp-feflood.h \ - sp-feflood-fns.h \ - sp-feimage.cpp sp-feimage.h \ - sp-feimage-fns.h \ - sp-femerge.cpp sp-femerge.h \ - sp-femerge-fns.h \ - sp-femergenode.cpp sp-femergenode.h \ - sp-femorphology.cpp sp-femorphology.h \ - sp-femorphology-fns.h \ - sp-feoffset.cpp sp-feoffset.h \ - sp-feoffset-fns.h \ - sp-fepointlight.cpp sp-fepointlight.h \ - sp-fespecularlighting.cpp sp-fespecularlighting.h \ - sp-fespecularlighting-fns.h \ - sp-fespotlight.cpp sp-fespotlight.h \ - sp-fetile.cpp sp-fetile.h \ - sp-fetile-fns.h \ - sp-feturbulence.cpp sp-feturbulence.h \ - sp-feturbulence-fns.h \ sp-filter-fns.h \ sp-filter-primitive.cpp \ sp-filter-primitive.h \ @@ -279,10 +244,6 @@ libinkpre_a_SOURCES = \ spiral-context.cpp spiral-context.h \ splivarot.cpp splivarot.h \ star-context.cpp star-context.h \ - streams-gzip.h streams-gzip.cpp \ - streams-handles.h streams-handles.cpp \ - streams-jar.h streams-jar.cpp \ - streams-zlib.h streams-zlib.cpp \ style.cpp style.h \ sp-style-elem.cpp sp-style-elem.h \ svg-profile.h \ @@ -356,6 +317,7 @@ inkscape_private_libs = \ pedro/libpedro.a \ trace/libtrace.a \ svg/libspsvg.a \ + filters/libfilters.a \ widgets/libspwidgets.a \ display/libspdisplay.a \ helper/libspchelp.a \ diff --git a/src/application/app-prototype.cpp b/src/application/app-prototype.cpp index 3af818824..3d9aa15e8 100644 --- a/src/application/app-prototype.cpp +++ b/src/application/app-prototype.cpp @@ -1,7 +1,7 @@ -/** - * \brief Base class for different application modes - * - * Author: +/** @file + * @brief Base class for different application modes + */ +/* Author: * Bryce W. Harrington <bryce@bryceharrington.org> * * Copyright (C) 2005 Bryce Harrington @@ -40,4 +40,4 @@ AppPrototype::~AppPrototype() fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
\ No newline at end of file diff --git a/src/application/app-prototype.h b/src/application/app-prototype.h index a7c8ad86f..a31bfa7d8 100644 --- a/src/application/app-prototype.h +++ b/src/application/app-prototype.h @@ -1,7 +1,7 @@ -/** - * \brief Base class for different application modes - * - * Author: +/** @file + * @brief Base class for different application modes + */ +/* Author: * Bryce W. Harrington <bryce@bryceharrington.org> * * Copyright (C) 2005 Bryce Harrington @@ -50,4 +50,4 @@ protected: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
\ No newline at end of file diff --git a/src/application/application.cpp b/src/application/application.cpp index c7aa28971..ab516b9d4 100644 --- a/src/application/application.cpp +++ b/src/application/application.cpp @@ -1,7 +1,7 @@ -/** \file - * \brief The top level class for managing the application. - * - * Authors: +/** @file + * @brief The top level class for managing the application + */ +/* Authors: * Bryce W. Harrington <bryce@bryceharrington.org> * Ralf Stephan <ralf@ark.in-berlin.de> * diff --git a/src/application/application.h b/src/application/application.h index 212add9e8..fce6bd47f 100644 --- a/src/application/application.h +++ b/src/application/application.h @@ -1,7 +1,7 @@ -/** \file - * \brief The top level class for managing the application. - * - * Authors: +/** @file + * @brief The top level class for managing the application. + */ +/* Authors: * Bryce W. Harrington <bryce@bryceharrington.org> * Ralf Stephan <ralf@ark.in-berlin.de> * diff --git a/src/application/editor.cpp b/src/application/editor.cpp index 0b8ac263e..24c811778 100644 --- a/src/application/editor.cpp +++ b/src/application/editor.cpp @@ -1,9 +1,9 @@ -/** \file - * \brief Editor Implementation class declaration for Inkscape. This +/** @file + * @brief Editor class declaration. This * singleton class implements much of the functionality of the former * 'inkscape' object and its services and signals. - * - * Authors: + */ +/* Authors: * Bryce W. Harrington <bryce@bryceharrington.org> * Derek P. Moore <derekm@hackunix.org> * Ralf Stephan <ralf@ark.in-berlin.de> diff --git a/src/application/editor.h b/src/application/editor.h index 1eed9a267..4545022b8 100644 --- a/src/application/editor.h +++ b/src/application/editor.h @@ -1,9 +1,8 @@ -/** \file - * \brief Class to manage an application used for editing SVG documents - * using GUI views - * - * \note This class is a Singleton - * +/** @file + * @brief Singleton class to manage an application used for editing SVG + * documents using GUI views + */ +/* * Authors: * Bryce W. Harrington <bryce@bryceharrington.org> * Ralf Stephan <ralf@ark.in-berlin.de> diff --git a/src/attributes-test.h b/src/attributes-test.h index 89be0eb4f..381821cd8 100644 --- a/src/attributes-test.h +++ b/src/attributes-test.h @@ -347,7 +347,6 @@ struct {char const *attr; bool supported;} const all_attrs[] = { {"inkscape:bbox-nodes", true}, {"inkscape:snap-page", true}, {"inkscape:snap-global", true}, - {"inkscape:snap-indicator", true}, {"inkscape:snap-bbox", true}, {"inkscape:snap-nodes", true}, {"inkscape:snap-guide", true}, diff --git a/src/attributes.cpp b/src/attributes.cpp index add2c8caf..149d177f5 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -87,7 +87,6 @@ static SPStyleProp const props[] = { {SP_ATTR_INKSCAPE_WINDOW_X, "inkscape:window-x"}, {SP_ATTR_INKSCAPE_WINDOW_Y, "inkscape:window-y"}, {SP_ATTR_INKSCAPE_SNAP_GLOBAL, "inkscape:snap-global"}, - {SP_ATTR_INKSCAPE_SNAP_INDICATOR, "inkscape:snap-indicator"}, {SP_ATTR_INKSCAPE_SNAP_BBOX, "inkscape:snap-bbox"}, {SP_ATTR_INKSCAPE_SNAP_NODES, "inkscape:snap-nodes"}, {SP_ATTR_INKSCAPE_SNAP_GUIDE, "inkscape:snap-guide"}, diff --git a/src/attributes.h b/src/attributes.h index e15822411..f8925f47c 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -87,7 +87,6 @@ enum SPAttributeEnum { SP_ATTR_INKSCAPE_WINDOW_X, SP_ATTR_INKSCAPE_WINDOW_Y, SP_ATTR_INKSCAPE_SNAP_GLOBAL, - SP_ATTR_INKSCAPE_SNAP_INDICATOR, SP_ATTR_INKSCAPE_SNAP_BBOX, SP_ATTR_INKSCAPE_SNAP_NODES, SP_ATTR_INKSCAPE_SNAP_GUIDE, diff --git a/src/bind/dobinding.cpp b/src/bind/dobinding.cpp index 6f9010533..1ba708ed7 100644 --- a/src/bind/dobinding.cpp +++ b/src/bind/dobinding.cpp @@ -1,6 +1,7 @@ /** - * This is a simple mechanism to bind Inkscape to Java, and thence - * to all of the nice things that can be layered upon that. + * @file + * @brief This is a simple mechanism to bind Inkscape to Java, and thence + * to all of the nice things that can be layered upon that. * * Authors: * Bob Jamison diff --git a/src/bind/javabind-private.h b/src/bind/javabind-private.h index 2530bd735..a03f0c1a2 100644 --- a/src/bind/javabind-private.h +++ b/src/bind/javabind-private.h @@ -1,7 +1,6 @@ -#ifndef __JAVABIND_PRIVATE_H__ -#define __JAVABIND_PRIVATE_H__ /** - * This is a simple mechanism to bind Inkscape to Java, and thence + * @file + * @brief This is a simple mechanism to bind Inkscape to Java, and thence * to all of the nice things that can be layered upon that. * * Authors: @@ -24,12 +23,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <jni.h> +#ifndef __JAVABIND_PRIVATE_H__ +#define __JAVABIND_PRIVATE_H__ +#include <jni.h> #include "javabind.h" - - namespace Inkscape { diff --git a/src/bind/javabind.cpp b/src/bind/javabind.cpp index e0e246d48..cb8c778b1 100644 --- a/src/bind/javabind.cpp +++ b/src/bind/javabind.cpp @@ -1,5 +1,6 @@ /** - * This is a simple mechanism to bind Inkscape to Java, and thence + * @file + * @brief This is a simple mechanism to bind Inkscape to Java, and thence * to all of the nice things that can be layered upon that. * * Authors: diff --git a/src/bind/javabind.h b/src/bind/javabind.h index 6ea896a2c..894f52d5d 100644 --- a/src/bind/javabind.h +++ b/src/bind/javabind.h @@ -1,7 +1,6 @@ -#ifndef __JAVABIND_H__ -#define __JAVABIND_H__ /** - * This is a simple mechanism to bind Inkscape to Java, and thence + * @file + * @brief This is a simple mechanism to bind Inkscape to Java, and thence * to all of the nice things that can be layered upon that. * * Authors: @@ -24,6 +23,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef __JAVABIND_H__ +#define __JAVABIND_H__ + #include <glibmm.h> #include <vector> diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 866cbbca4..241279100 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -216,7 +216,6 @@ box3d_side_set_shape (SPShape *shape) return; } - SPCurve *c = new SPCurve(); // TODO: Draw the correct quadrangle here // To do this, determine the perspective of the box, the orientation of the side (e.g., XY-FRONT) // compute the coordinates of the corners in P^3, project them onto the canvas, and draw the @@ -225,14 +224,24 @@ box3d_side_set_shape (SPShape *shape) unsigned int corners[4]; box3d_side_compute_corner_ids(side, corners); + SPCurve *c = new SPCurve(); c->moveto(box3d_get_corner_screen(box, corners[0])); c->lineto(box3d_get_corner_screen(box, corners[1])); c->lineto(box3d_get_corner_screen(box, corners[2])); c->lineto(box3d_get_corner_screen(box, corners[3])); - c->closepath(); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM (side), c); - sp_shape_set_curve_insync (SP_SHAPE (side), c, TRUE); + + /* Reset the shape'scurve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + sp_shape_set_curve_insync (shape, c, TRUE); + if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) { + SPCurve *c_lpe = c->copy(); + bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe); + if (success) { + sp_shape_set_curve_insync (shape, c_lpe, TRUE); + } + c_lpe->unref(); + } c->unref(); } diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index 34c839c6f..657850ec7 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -190,7 +190,7 @@ static Avoid::Polygn avoid_item_poly(SPItem const *item) // by the sp_*_update functions, e.g., text. sp_document_ensure_up_to_date(item->document); - boost::optional<Geom::Rect> rHull = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect rHull = item->getBounds(sp_item_i2doc_affine(item)); if (!rHull) { return Avoid::newPoly(0); } diff --git a/src/connector-context.cpp b/src/connector-context.cpp index ef89c290f..8260456d4 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -602,7 +602,7 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons if (connector_within_tolerance) { gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - if ( NR::LInfty( event_w - connector_drag_origin_w ) < tolerance ) { + if ( Geom::LInfty( event_w - connector_drag_origin_w ) < tolerance ) { return FALSE; // Do not drag if we're within tolerance from origin. } } @@ -1149,7 +1149,7 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item) } - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(cc->active_shape); + Geom::OptRect bbox = sp_item_bbox_desktop(cc->active_shape); if (bbox) { Geom::Point center = bbox->midpoint(); sp_knot_set_position(cc->connpthandle, center, 0); diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 07817529d..c92bcfdf5 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -25,7 +25,7 @@ #include "style.h" #include "preferences.h" #include "sp-use.h" -#include "sp-feblend.h" +#include "filters/blend.h" #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-gaussian-blur.h" diff --git a/src/desktop.cpp b/src/desktop.cpp index 1ee24f9c6..cd39e77ae 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -535,7 +535,7 @@ bool SPDesktop::isLayer(SPObject *object) const { bool SPDesktop::isWithinViewport (SPItem *item) const { Geom::Rect const viewport = get_display_area(); - boost::optional<Geom::Rect> const bbox = sp_item_bbox_desktop(item); + Geom::OptRect const bbox = sp_item_bbox_desktop(item); if (bbox) { return viewport.contains(*bbox); } else { @@ -756,7 +756,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double // FIXME: This 2geom idiom doesn't allow us to declare dbox const Geom::Rect viewbox = canvas->getViewbox(); - viewbox.expandBy(border); + viewbox.expandBy(-border); double scale = _d2w.descrim(); double newscale; @@ -937,8 +937,8 @@ SPDesktop::zoom_quick (bool enable) } if (!zoomed) { - boost::optional<Geom::Rect> const d = selection->bounds(); - if (d && !d->isEmpty() && d->area() * 2.0 < _quick_zoom_stored_area.area()) { + Geom::OptRect const d = selection->bounds(); + if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) { set_display_area(*d, 10); zoomed = true; } @@ -1038,8 +1038,7 @@ SPDesktop::zoom_page() Geom::Rect d(Geom::Point(0, 0), Geom::Point(sp_document_width(doc()), sp_document_height(doc()))); - // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 1.0; is it safe to ignore it? - if (d.isEmpty()) { + if (d.minExtent() < 1.0) { return; } @@ -1070,10 +1069,9 @@ SPDesktop::zoom_page_width() void SPDesktop::zoom_selection() { - boost::optional<Geom::Rect> const d = selection->bounds(); + Geom::OptRect const d = selection->bounds(); - // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 0.1; is it safe to ignore it? - if ( !d || d->isEmpty() ) { + if ( !d || d->minExtent() < 0.1 ) { return; } @@ -1099,13 +1097,12 @@ SPDesktop::zoom_drawing() SPItem *docitem = SP_ITEM (sp_document_root (doc())); g_return_if_fail (docitem != NULL); - boost::optional<Geom::Rect> d = sp_item_bbox_desktop(docitem); + Geom::OptRect d = sp_item_bbox_desktop(docitem); /* Note that the second condition here indicates that ** there are no items in the drawing. */ - // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 1.0; is it safe to ignore it? - if ( !d || d->isEmpty() ) { + if ( !d || d->minExtent() < 0.1 ) { return; } diff --git a/src/dialogs/CMakeLists.txt b/src/dialogs/CMakeLists.txt index 4087fbfe9..e9fa7c6fc 100644 --- a/src/dialogs/CMakeLists.txt +++ b/src/dialogs/CMakeLists.txt @@ -1,6 +1,5 @@ SET(dialogs_SRC clonetiler.cpp -debugdialog.cpp dialog-events.cpp eek-color-def.cpp eek-preview.cpp @@ -21,7 +20,6 @@ sp-attribute-widget.cpp stroke-style.cpp swatches.cpp text-edit.cpp -tiledialog.cpp unclump.cpp xml-tree.cpp ) diff --git a/src/dialogs/Makefile_insert b/src/dialogs/Makefile_insert index 4b1d42abb..5d5614668 100644 --- a/src/dialogs/Makefile_insert +++ b/src/dialogs/Makefile_insert @@ -13,57 +13,53 @@ dialogs/all: dialogs/libspdialogs.a dialogs/clean: rm -f dialogs/libspdialogs.a $(dialogs_libspdialogs_a_OBJECTS) -dialogs_libspdialogs_a_SOURCES = \ - dialogs/debugdialog.cpp \ - dialogs/debugdialog.h \ +dialogs_libspdialogs_a_SOURCES = \ + dialogs/clonetiler.cpp \ + dialogs/clonetiler.h \ dialogs/dialog-events.cpp \ - dialogs/dialog-events.h \ - dialogs/eek-color-def.h \ + dialogs/dialog-events.h \ dialogs/eek-color-def.cpp \ - dialogs/eek-preview.h \ - dialogs/eek-preview.cpp \ - dialogs/export.cpp \ - dialogs/export.h \ - dialogs/extensions.cpp \ - dialogs/extensions.h \ - dialogs/fill-style.cpp \ - dialogs/fill-style.h \ + dialogs/eek-color-def.h \ + dialogs/eek-preview.cpp \ + dialogs/eek-preview.h \ + dialogs/export.cpp \ + dialogs/export.h \ + dialogs/extensions.cpp \ + dialogs/extensions.h \ + dialogs/fill-style.cpp \ + dialogs/fill-style.h \ + dialogs/find.cpp \ + dialogs/find.h \ dialogs/guidelinedialog.cpp \ dialogs/guidelinedialog.h \ + dialogs/iconpreview.cpp \ + dialogs/iconpreview.h \ dialogs/in-dt-coordsys.cpp \ dialogs/in-dt-coordsys.h \ - dialogs/input.cpp \ - dialogs/input.h \ + dialogs/input.cpp \ + dialogs/input.h \ dialogs/item-properties.cpp \ dialogs/item-properties.h \ dialogs/layer-properties.cpp \ dialogs/layer-properties.h \ dialogs/layers-panel.cpp \ - dialogs/layers-panel.h \ + dialogs/layers-panel.h \ dialogs/object-attributes.cpp \ dialogs/object-attributes.h \ + dialogs/rdf.cpp \ + dialogs/rdf.h \ dialogs/sp-attribute-widget.cpp \ dialogs/sp-attribute-widget.h \ dialogs/stroke-style.cpp \ - dialogs/stroke-style.h \ - dialogs/swatches.cpp \ - dialogs/swatches.h \ - dialogs/text-edit.cpp \ - dialogs/text-edit.h \ - dialogs/tiledialog.cpp \ - dialogs/tiledialog.h \ - dialogs/xml-tree.cpp \ - dialogs/xml-tree.h \ - dialogs/rdf.cpp \ - dialogs/rdf.h \ - dialogs/find.cpp \ - dialogs/find.h \ - dialogs/clonetiler.cpp \ - dialogs/clonetiler.h \ - dialogs/unclump.cpp \ - dialogs/unclump.h \ - dialogs/iconpreview.cpp \ - dialogs/iconpreview.h + dialogs/stroke-style.h \ + dialogs/swatches.cpp \ + dialogs/swatches.h \ + dialogs/text-edit.cpp \ + dialogs/text-edit.h \ + dialogs/unclump.cpp \ + dialogs/unclump.h \ + dialogs/xml-tree.cpp \ + dialogs/xml-tree.h # dialogs/sp-widget.c \ # dialogs/sp-widget.h \ diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index ce0fc15df..d1074ef73 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -1,14 +1,12 @@ -#define __SP_CLONE_TILER_C__ - -/* +/** @file * Clone tiling dialog - * - * Authors: + */ +/* Authors: * bulia byak <buliabyak@users.sf.net> * Johan Engelen <goejendaagh@zonnet.nl> * * Copyright (C) 2004-2006 Authors - * Released under GNU GPL + * Released under GNU GPL, read the file 'COPYING' for more information */ #ifdef HAVE_CONFIG_H @@ -1246,7 +1244,7 @@ clonetiler_apply( GtkWidget */*widget*/, void * ) bool prefs_bbox = prefs->getBool("/tools/bounding_box", false); SPItem::BBoxType bbox_type = ( prefs_bbox ? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX ); - boost::optional<Geom::Rect> r = SP_ITEM(obj)->getBounds(sp_item_i2doc_affine(SP_ITEM(obj)), + Geom::OptRect r = SP_ITEM(obj)->getBounds(sp_item_i2doc_affine(SP_ITEM(obj)), bbox_type); if (r) { w = r->dimensions()[Geom::X]; diff --git a/src/dialogs/clonetiler.h b/src/dialogs/clonetiler.h index 82206818c..6bfb257a4 100644 --- a/src/dialogs/clonetiler.h +++ b/src/dialogs/clonetiler.h @@ -1,15 +1,14 @@ -#ifndef __SP_CLONE_TILER_H__ -#define __SP_CLONE_TILER_H__ - -/** - * \brief Clone tiling dialog - * - * Authors: - * bulia byak +/** @file + * @brief Clone tiling dialog + */ +/* Authors: + * bulia byak <buliabyak@users.sf.net> * * Copyright (C) 2004 Authors - * + * Released under the GNU GPL, read the file 'COPYING' for more information */ +#ifndef __SP_CLONE_TILER_H__ +#define __SP_CLONE_TILER_H__ #include <glib.h> diff --git a/src/dialogs/dialog-events.cpp b/src/dialogs/dialog-events.cpp index b306e42d6..da55936ce 100644 --- a/src/dialogs/dialog-events.cpp +++ b/src/dialogs/dialog-events.cpp @@ -1,9 +1,7 @@ -#define __DIALOG_EVENTS_C__ - -/** - * \brief Event handler for dialog windows - * - * Authors: +/** @file + * @brief Event handler for dialog windows + */ +/* Authors: * bulia byak <bulia@dr.com> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> * @@ -31,9 +29,9 @@ /** -* \brief This function is called to zero the transientize semaphore by a -* timeout. -*/ + * \brief This function is called to zero the transientize semaphore by a + * timeout. + */ gboolean sp_allow_again (gpointer *wd) { diff --git a/src/dialogs/dialog-events.h b/src/dialogs/dialog-events.h index 46cbc7a67..2fca84ad2 100644 --- a/src/dialogs/dialog-events.h +++ b/src/dialogs/dialog-events.h @@ -1,10 +1,7 @@ -#ifndef __DIALOG_EVENTS_H__ -#define __DIALOG_EVENTS_H__ - -/** - * \brief Event handler for dialog windows - * - * Authors: +/** @file + * @brief Event handler for dialog windows + */ +/* Authors: * bulia byak <bulia@dr.com> * * Copyright (C) 2003 authors @@ -12,6 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef __DIALOG_EVENTS_H__ +#define __DIALOG_EVENTS_H__ + #include <gtk/gtkstyle.h> #include <gtk/gtkwindow.h> #include <forward.h> @@ -31,8 +31,8 @@ class Entry; } typedef struct { - GtkWidget *win; - guint stop; + GtkWidget *win; + guint stop; } win_data; diff --git a/src/dialogs/eek-color-def.cpp b/src/dialogs/eek-color-def.cpp index 9a079b68f..85b00b251 100644 --- a/src/dialogs/eek-color-def.cpp +++ b/src/dialogs/eek-color-def.cpp @@ -1,5 +1,5 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/** @file + * @brief EEK color definition */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -133,5 +133,15 @@ void ColorDef::removeCallback( ColorCallback cb, void* data ) (void)data; } - } // namespace eek + +/* + 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/dialogs/eek-color-def.h b/src/dialogs/eek-color-def.h index e17e8a596..63cd096be 100644 --- a/src/dialogs/eek-color-def.h +++ b/src/dialogs/eek-color-def.h @@ -1,7 +1,5 @@ -#ifndef SEEN_EEK_COLOR_DEF_H -#define SEEN_EEK_COLOR_DEF_H -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/** @file + * @brief EEK color definition */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -39,6 +37,9 @@ * * ***** END LICENSE BLOCK ***** */ +#ifndef SEEN_EEK_COLOR_DEF_H +#define SEEN_EEK_COLOR_DEF_H + #include <string> #include <vector> @@ -87,5 +88,15 @@ private: } // namespace eek - #endif // SEEN_EEK_COLOR_DEF_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:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/eek-preview.cpp b/src/dialogs/eek-preview.cpp index 145346af3..f9aadc561 100644 --- a/src/dialogs/eek-preview.cpp +++ b/src/dialogs/eek-preview.cpp @@ -1,5 +1,5 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/** @file + * @brief EEK preview stuff */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -655,27 +655,27 @@ static void eek_preview_init( EekPreview *preview ) /* GTK_STATE_SELECTED, */ /* GTK_STATE_INSENSITIVE */ - if ( 0 ) { - GdkColor color = {0,0,0,0}; - - color.red = 0xffff; - color.green = 0; - color.blue = 0xffff; - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); - gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color); - - color.red = 0; - color.green = 0xffff; - color.blue = 0; - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); - gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color); - - color.red = 0xffff; - color.green = 0; - color.blue = 0; - gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); - gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color ); - } + if ( 0 ) { + GdkColor color = {0,0,0,0}; + + color.red = 0xffff; + color.green = 0; + color.blue = 0xffff; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color); + + color.red = 0; + color.green = 0xffff; + color.blue = 0; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color); + + color.red = 0xffff; + color.green = 0; + color.blue = 0; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color ); + } } @@ -684,3 +684,13 @@ GtkWidget* eek_preview_new(void) return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) ); } +/* + 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/dialogs/eek-preview.h b/src/dialogs/eek-preview.h index ee99125af..40597eb48 100644 --- a/src/dialogs/eek-preview.h +++ b/src/dialogs/eek-preview.h @@ -1,7 +1,5 @@ -#ifndef SEEN_EEK_PREVIEW_H -#define SEEN_EEK_PREVIEW_H -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * +/** @file + * @brief EEK preview stuff */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -39,6 +37,9 @@ * * ***** END LICENSE BLOCK ***** */ +#ifndef SEEN_EEK_PREVIEW_H +#define SEEN_EEK_PREVIEW_H + #include <gtk/gtkdrawingarea.h> G_BEGIN_DECLS @@ -131,5 +132,15 @@ void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes ); G_END_DECLS - #endif /* SEEN_EEK_PREVIEW_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:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp index dc337ef8e..f1a68c999 100644 --- a/src/dialogs/export.cpp +++ b/src/dialogs/export.cpp @@ -1,11 +1,7 @@ -#define __SP_EXPORT_C__ - -/** \file - * \brief PNG export dialog +/** @file + * @brief PNG export dialog */ - -/* - * Authors: +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> @@ -317,7 +313,7 @@ sp_export_dialog_area_box (GtkWidget * dlg) dlg ); sp_export_spinbutton_new ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - us->gobj(), GTK_WIDGET(t->gobj()), 4, 0, _("Width:"), NULL, EXPORT_COORD_PRECISION, 1, + us->gobj(), GTK_WIDGET(t->gobj()), 4, 0, _("Wid_th:"), NULL, EXPORT_COORD_PRECISION, 1, G_CALLBACK (sp_export_area_width_value_changed), dlg ); @@ -333,7 +329,7 @@ sp_export_dialog_area_box (GtkWidget * dlg) dlg ); sp_export_spinbutton_new ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - us->gobj(), GTK_WIDGET(t->gobj()), 4, 1, _("Height:"), NULL, EXPORT_COORD_PRECISION, 1, + us->gobj(), GTK_WIDGET(t->gobj()), 4, 1, _("Hei_ght:"), NULL, EXPORT_COORD_PRECISION, 1, G_CALLBACK (sp_export_area_height_value_changed), dlg ); @@ -492,7 +488,7 @@ sp_export_dialog (void) sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, NULL, GTK_WIDGET(t->gobj()), 0, 1, - _("Height:"), _("pixels at"), 0, 1, + _("_Height:"), _("pixels at"), 0, 1, G_CALLBACK (sp_export_bitmap_height_value_changed), dlg ); @@ -626,7 +622,7 @@ sp_export_dialog (void) { Gtk::HBox* hide_box = new Gtk::HBox(FALSE, 5); - GtkWidget *he = gtk_check_button_new_with_label(_("Hide all except selected")); + GtkWidget *he = gtk_check_button_new_with_label(_("Hide _all except selected")); gtk_widget_set_sensitive(GTK_WIDGET(he), TRUE); gtk_object_set_data(GTK_OBJECT(dlg), "hide_checkbox", he); hide_box->pack_start(*Glib::wrap(he), false, false); @@ -778,7 +774,7 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/, if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); + Geom::OptRect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); if (bbox) { sp_export_set_area (base, bbox->min()[Geom::X], bbox->min()[Geom::Y], @@ -837,7 +833,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; - boost::optional<Geom::Rect> bbox; + Geom::OptRect bbox; doc = sp_desktop_document (SP_ACTIVE_DESKTOP); /* Notice how the switch is used to 'fall through' here to get @@ -1102,26 +1098,27 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base) dpi = DPI_BASE; } - NRRect area; - sp_item_invoke_bbox(item, &area, sp_item_i2r_affine((SPItem *) item), TRUE); - - gint width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); - gint height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); - - if (width > 1 && height > 1) { - /* Do export */ - if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), fn, - area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, - nv->pagecolor, - NULL, NULL, TRUE, // overwrite without asking - hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL - )) { - gchar * error; - gchar * safeFile = Inkscape::IO::sanitizeString(fn); - error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); - sp_ui_error_dialog(error); - g_free(safeFile); - g_free(error); + Geom::OptRect area; + sp_item_invoke_bbox(item, area, sp_item_i2r_affine((SPItem *) item), TRUE); + if (area) { + gint width = (gint) (area->width() * dpi / PX_PER_IN + 0.5); + gint height = (gint) (area->height() * dpi / PX_PER_IN + 0.5); + + if (width > 1 && height > 1) { + /* Do export */ + if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), fn, + *area, width, height, dpi, dpi, + nv->pagecolor, + NULL, NULL, TRUE, // overwrite without asking + hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL + )) { + gchar * error; + gchar * safeFile = Inkscape::IO::sanitizeString(fn); + error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); + sp_ui_error_dialog(error); + g_free(safeFile); + g_free(error); + } } } n++; @@ -1183,7 +1180,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base) /* Do export */ if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), filename_ext, - x0, y0, x1, y1, width, height, xdpi, ydpi, + Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, nv->pagecolor, sp_export_progress_callback, base, FALSE, hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL @@ -1407,7 +1404,7 @@ sp_export_detect_size(GtkObject * base) { switch (this_test[i]) { case SELECTION_SELECTION: if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - boost::optional<Geom::Rect> bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(); + Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(); //std::cout << "Selection " << bbox; if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) { @@ -1418,7 +1415,7 @@ sp_export_detect_size(GtkObject * base) { case SELECTION_DRAWING: { SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); + Geom::OptRect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); // std::cout << "Drawing " << bbox2; if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) { @@ -1969,9 +1966,9 @@ sp_export_filename_modified (GtkObject * object, gpointer data) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + 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 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/export.h b/src/dialogs/export.h index 3bb0a1375..801ddc91a 100644 --- a/src/dialogs/export.h +++ b/src/dialogs/export.h @@ -1,14 +1,24 @@ +/** @file + * @brief export to bitmap dialog + */ +/* Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * bulia byak <buliabyak@users.sf.net> + * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> + * + * Copyright (C) 1999-2007 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + #ifndef SP_EXPORT_H #define SP_EXPORT_H /** - * \brief export to bitmap dialog - * * Creates a dialog window for exporting an image to a bitmap if one doesn't already exist and - * shows it to the user. If the dialog has already been created, it simply shows the window. - * + * shows it to the user. If the dialog has already been created, it simply shows the window. */ - void sp_export_dialog (void); #endif diff --git a/src/dialogs/extensions.cpp b/src/dialogs/extensions.cpp index e363df607..f168da33a 100644 --- a/src/dialogs/extensions.cpp +++ b/src/dialogs/extensions.cpp @@ -1,16 +1,13 @@ -/* - * A simple dialog for previewing icon representation. - * - * Authors: +/** @file + * @brief A simple dialog with information about extensions + */ +/* Authors: * Jon A. Cruz * * Copyright (C) 2005 Jon A. Cruz * * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif #include <gtk/gtkdialog.h> //for GTK_RESPONSE* types #include <gtkmm/scrolledwindow.h> @@ -116,8 +113,17 @@ void ExtensionsPanel::rescan() // g_message("\\------------------"); } - - } //namespace Dialogs } //namespace UI } //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/dialogs/extensions.h b/src/dialogs/extensions.h index e253ab849..8b0fc2780 100644 --- a/src/dialogs/extensions.h +++ b/src/dialogs/extensions.h @@ -1,24 +1,23 @@ - -#ifndef SEEN_EXTENSIONS_H -#define SEEN_EXTENSIONS_H -/* - * A simple dialog for previewing icon representation. - * - * Authors: +/** @file + * A simple dialog with information about extensions + */ +/* Authors: * Jon A. Cruz * * Copyright (C) 2005 The Inkscape Organization - * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#ifndef SEEN_EXTENSIONS_H +#define SEEN_EXTENSIONS_H #include <gtkmm/textview.h> #include "ui/widget/panel.h" namespace Inkscape { - namespace Extension { - class Extension; - } +namespace Extension { +class Extension; +} } namespace Inkscape { @@ -54,6 +53,4 @@ private: } //namespace UI } //namespace Inkscape - - #endif // SEEN_EXTENSIONS_H diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp index e095425a9..e1c30e7ae 100644 --- a/src/dialogs/fill-style.cpp +++ b/src/dialogs/fill-style.cpp @@ -1,9 +1,7 @@ -#define __SP_FILL_STYLE_C__ - -/** - * \brief Fill style widget - * - * Authors: +/** @file + * @brief Fill style widget + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * Frank Felfe <innerspace@iname.com> * bulia byak <buliabyak@users.sf.net> diff --git a/src/dialogs/fill-style.h b/src/dialogs/fill-style.h index 96cb06987..3924412ec 100644 --- a/src/dialogs/fill-style.h +++ b/src/dialogs/fill-style.h @@ -1,10 +1,7 @@ -#ifndef __SP_FILL_STYLE_H__ -#define __SP_FILL_STYLE_H__ - -/** - * \brief Fill style configuration - * - * Authors: +/** @file + * @brief Fill style configuration + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * * Copyright (C) 2002 Lauris Kaplinski @@ -12,10 +9,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> +#ifndef SEEN_DIALOGS_SP_FILL_STYLE_H +#define SEEN_DIALOGS_SP_FILL_STYLE_H +#include <glib.h> #include <gtk/gtkwidget.h> - #include "forward.h" diff --git a/src/dialogs/find.cpp b/src/dialogs/find.cpp index 96a630553..29a0fe7e8 100644 --- a/src/dialogs/find.cpp +++ b/src/dialogs/find.cpp @@ -1,9 +1,7 @@ -#define __SP_TRANSFORMATION_C__ - -/** - * \brief Find dialog - * - * Authors: +/** @file + * @brief Find dialog + */ +/* Authors: * bulia byak <bulia@users.sf.net> * * Copyright (C) 2004 Authors @@ -11,13 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - #include "widgets/icon.h" - #include "message-stack.h" //TODO : delete this @@ -69,9 +61,6 @@ sp_find_dialog(){ #define MIN_ONSCREEN_DISTANCE 50 -using NR::X; -using NR::Y; - static GtkWidget *dlg = NULL; static win_data wd; diff --git a/src/dialogs/find.h b/src/dialogs/find.h index 38200d532..fe5861a73 100644 --- a/src/dialogs/find.h +++ b/src/dialogs/find.h @@ -1,10 +1,7 @@ -#ifndef SEEN_FIND_H -#define SEEN_FIND_H - -/** - * \brief Find dialog - * - * Authors: +/** @file + * @brief Find dialog + */ +/* Authors: * bulia byak <bulia@users.sf.net> * * Copyright (C) 2004 Authors @@ -12,6 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_FIND_H +#define SEEN_FIND_H + #include <gtk/gtkstyle.h> void sp_find_dialog(); diff --git a/src/dialogs/guidelinedialog.cpp b/src/dialogs/guidelinedialog.cpp index 1dc23cb2b..f0115ee91 100644 --- a/src/dialogs/guidelinedialog.cpp +++ b/src/dialogs/guidelinedialog.cpp @@ -1,9 +1,7 @@ -#define __GUIDELINE_CPP__ - -/* - * simple guideline dialog - * - * Authors: +/** @file + * @brief Simple guideline dialog + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * Andrius R. <knutux@gmail.com> * Johan Engelen @@ -285,4 +283,3 @@ void GuidelinePropertiesDialog::_setup() { End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : - diff --git a/src/dialogs/iconpreview.cpp b/src/dialogs/iconpreview.cpp index f31914e3e..4d402d235 100644 --- a/src/dialogs/iconpreview.cpp +++ b/src/dialogs/iconpreview.cpp @@ -1,7 +1,7 @@ -/* - * A simple dialog for previewing icon representation. - * - * Authors: +/** @file + * @brief A simple dialog for previewing icon representation. + */ +/* Authors: * Jon A. Cruz * Bob Jamison * Other dudes from The Inkscape Organization diff --git a/src/dialogs/iconpreview.h b/src/dialogs/iconpreview.h index 3a3652334..8f143725d 100644 --- a/src/dialogs/iconpreview.h +++ b/src/dialogs/iconpreview.h @@ -1,9 +1,7 @@ -#ifndef SEEN_ICON_PREVIEW_H -#define SEEN_ICON_PREVIEW_H -/* - * A simple dialog for previewing icon representation. - * - * Authors: +/** @file + * @brief A simple dialog for previewing icon representation. + */ +/* Authors: * Jon A. Cruz * Bob Jamison * Other dudes from The Inkscape Organization @@ -13,6 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_ICON_PREVIEW_H +#define SEEN_ICON_PREVIEW_H + #include <gtkmm/box.h> #include <gtkmm/button.h> #include <gtkmm/label.h> diff --git a/src/dialogs/in-dt-coordsys.h b/src/dialogs/in-dt-coordsys.h index 6078f9b41..c2ec96d8e 100644 --- a/src/dialogs/in-dt-coordsys.h +++ b/src/dialogs/in-dt-coordsys.h @@ -4,7 +4,6 @@ bool in_dt_coordsys(SPObject const &item); - #endif /* !SEEN_IN_DT_COORDSYS */ /* diff --git a/src/dialogs/input.cpp b/src/dialogs/input.cpp index e23fcc848..0b4587f55 100644 --- a/src/dialogs/input.cpp +++ b/src/dialogs/input.cpp @@ -1,5 +1,3 @@ -#define __SP_INPUT_C__ - /** @file * @brief Extended input devices dialog */ @@ -13,8 +11,9 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +# include <config.h> #endif + #include <gtk/gtksignal.h> #include <gtk/gtkinputdialog.h> #include <glibmm/ustring.h> diff --git a/src/dialogs/input.h b/src/dialogs/input.h index 70e68774e..0996d06ca 100644 --- a/src/dialogs/input.h +++ b/src/dialogs/input.h @@ -1,10 +1,7 @@ -#ifndef __SP_INPUT_H__ -#define __SP_INPUT_H__ - -/** - * \brief Extended input device dialog - * - * Author: +/** @file + * @brief Extended input device dialog + */ +/* Author: * Nicklas Lindgren <nili@lysator.liu.se> * * Copyright (C) 2005 Authors @@ -12,6 +9,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_DIALOGS_INPUT_H +#define SEEN_DIALOGS_INPUT_H void sp_input_load_from_preferences (void); void sp_input_save_to_preferences (void); diff --git a/src/dialogs/item-properties.cpp b/src/dialogs/item-properties.cpp index 808775786..d1992b158 100644 --- a/src/dialogs/item-properties.cpp +++ b/src/dialogs/item-properties.cpp @@ -1,9 +1,7 @@ -#define __SP_ITEM_PROPERTIES_C__ - -/* - * Object properties dialog - * - * Authors: +/** @file + * @brief Object properties dialog + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <goejendaagh@zonnet.nl> diff --git a/src/dialogs/item-properties.h b/src/dialogs/item-properties.h index a81034aae..9815a1fc5 100644 --- a/src/dialogs/item-properties.h +++ b/src/dialogs/item-properties.h @@ -1,20 +1,17 @@ -#ifndef __SP_ITEM_PROPERTIES_H__ -#define __SP_ITEM_PROPERTIES_H__ - -/** +/** @file * \brief Display settings dialog - * - * Author: + */ +/* Author: * Lauris Kaplinski <lauris@ximian.com> * * Copyright (C) 2001 Ximian, Inc. - * + * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> - - +#ifndef SEEN_DIALOGS_ITEM_PROPERTIES_H +#define SEEN_DIALOGS_ITEM_PROPERTIES_H +#include <glib.h> #include <gtk/gtkwidget.h> #include "../forward.h" @@ -22,8 +19,6 @@ GtkWidget *sp_item_widget_new (void); void sp_item_dialog (void); - - #endif /* diff --git a/src/dialogs/layer-properties.cpp b/src/dialogs/layer-properties.cpp index bd95fbc71..ccd91fa2e 100644 --- a/src/dialogs/layer-properties.cpp +++ b/src/dialogs/layer-properties.cpp @@ -1,8 +1,7 @@ -/** - * - * \brief Dialog for renaming layers - * - * Author: +/** @file + * @brief Dialog for renaming layers + */ +/* Author: * Bryce W. Harrington <bryce@bryceharrington.com> * Andrius R. <knutux@gmail.com> * @@ -12,12 +11,7 @@ * Released under GNU GPL. Read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - #include <gtkmm/stock.h> - #include <glibmm/i18n.h> #include "inkscape.h" #include "desktop.h" diff --git a/src/dialogs/layer-properties.h b/src/dialogs/layer-properties.h index 58bed141d..807967e8d 100644 --- a/src/dialogs/layer-properties.h +++ b/src/dialogs/layer-properties.h @@ -1,8 +1,7 @@ -/** - * - * \brief Dialog for renaming layers - * - * Author: +/** @file + * @brief Dialog for renaming layers + */ +/* Author: * Bryce W. Harrington <bryce@bryceharrington.com> * * Copyright (C) 2004 Bryce Harrington diff --git a/src/dialogs/layers-panel.h b/src/dialogs/layers-panel.h index 62596e407..1f593b9c6 100644 --- a/src/dialogs/layers-panel.h +++ b/src/dialogs/layers-panel.h @@ -1,5 +1,3 @@ -#ifndef SEEN_LAYERS_PANEL_H -#define SEEN_LAYERS_PANEL_H /* * A simple dialog for layer UI. * @@ -11,6 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_LAYERS_PANEL_H +#define SEEN_LAYERS_PANEL_H + #include <gtkmm/treeview.h> #include <gtkmm/treestore.h> #include <gtkmm/tooltips.h> diff --git a/src/dialogs/object-attributes.cpp b/src/dialogs/object-attributes.cpp index e0c891ea1..d9bcf1489 100644 --- a/src/dialogs/object-attributes.cpp +++ b/src/dialogs/object-attributes.cpp @@ -1,9 +1,7 @@ -#define __SP_OBJECT_ATTRIBUTES_C__ - -/** - * \brief Generic properties editor - * - * Authors: +/** @file + * @brief Generic properties editor + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * @@ -12,10 +10,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <glibmm/i18n.h> #include <string> #include <cstring> @@ -149,11 +143,8 @@ sp_object_attributes_dialog (SPObject *object, const gchar *tag) sp_object_attr_show_dialog (object, image_desc, tag); } } - } // end of sp_object_attributes_dialog() - - /* Local Variables: mode:c++ diff --git a/src/dialogs/object-attributes.h b/src/dialogs/object-attributes.h index 2fc562e16..726d8e43b 100644 --- a/src/dialogs/object-attributes.h +++ b/src/dialogs/object-attributes.h @@ -1,10 +1,7 @@ -#ifndef __SP_OBJECT_ATTRIBUTES_H__ -#define __SP_OBJECT_ATTRIBUTES_H__ - -/** - * \brief Generic object attribute editor - * - * Author: +/** @file + * @brief Generic object attribute editor + */ +/* Author: * Lauris Kaplinski <lauris@ximian.com> * * Copyright (C) 2001 Ximian, Inc. @@ -12,17 +9,15 @@ * Licensed under GNU GPL */ -#include <glib.h> - - +#ifndef SEEN_DIALOGS_OBJECT_ATTRIBUTES_H +#define SEEN_DIALOGS_OBJECT_ATTRIBUTES_H +#include <glib.h> #include <gtk/gtkwidget.h> #include "../forward.h" void sp_object_attributes_dialog (SPObject *object, const gchar *tag); - - #endif /* diff --git a/src/dialogs/rdf.cpp b/src/dialogs/rdf.cpp index 70cac4e1f..f0b174922 100644 --- a/src/dialogs/rdf.cpp +++ b/src/dialogs/rdf.cpp @@ -1,9 +1,9 @@ -/** - * \brief RDF manipulation functions - * - * FIXME: move these to xml/ instead of dialogs/ +/** @file + * @brief RDF manipulation functions * - * Authors: + * @todo move these to xml/ instead of dialogs/ + */ +/* Authors: * Kees Cook <kees@outflux.net> * Jon Phillips <jon@rejon.org> * @@ -11,22 +11,14 @@ * Copyright (C) 2006 Jon Phillips <jon@rejon.org> * * Released under GNU GPL, read the file 'COPYING' for more information - * */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - - - #include "xml/repr.h" #include "rdf.h" #include "sp-item-group.h" #include "inkscape.h" /* - Example RDF XML from various places... <rdf:RDF xmlns="http://creativecommons.org/ns#" @@ -83,8 +75,6 @@ Bag example: <rdf:li>filetype</rdf:li> </rdf:Bag> </dc:subject> - - */ struct rdf_double_t rdf_license_empty [] = { @@ -1021,7 +1011,6 @@ rdf_set_defaults ( SPDocument * doc ) } } - /* Local Variables: mode:c++ @@ -1031,4 +1020,4 @@ rdf_set_defaults ( SPDocument * doc ) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/rdf.h b/src/dialogs/rdf.h index 4c907e7aa..a98f5a1e4 100644 --- a/src/dialogs/rdf.h +++ b/src/dialogs/rdf.h @@ -1,20 +1,16 @@ -/** - * - * \brief headers for RDF types - * - * Authors: +/** @file + * @brief headers for RDF types + */ +/* Authors: * Kees Cook <kees@outflux.net> * - * Copyright (C) 2004 Kees Cook <kees@outflux.net> - * + * Copyright (C) 2004 Authors * Released under GNU GPL, read the file 'COPYING' for more information - * */ #ifndef _RDF_H_ #define _RDF_H_ #include <glib.h> - #include <glibmm/i18n.h> #include "document.h" @@ -121,4 +117,4 @@ void rdf_set_defaults ( SPDocument * doc ); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/sp-attribute-widget.cpp b/src/dialogs/sp-attribute-widget.cpp index 9848d9f26..de14fc173 100644 --- a/src/dialogs/sp-attribute-widget.cpp +++ b/src/dialogs/sp-attribute-widget.cpp @@ -1,20 +1,12 @@ -#define __SP_ATTRIBUTE_WIDGET_C__ - -/** - * \brief SPAttributeWidget - * - * Widget, that listens and modifies repr attributes - * - * Authors: +/** @file + * @brief Widget that listens and modifies repr attributes + */ +/* Authors: * Lauris Kaplinski <lauris@ximian.com> * * Copyright (C) 2001 Ximian, Inc. - * - * Licensed under GNU GPL + * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif #include <gtk/gtktable.h> #include <gtk/gtklabel.h> diff --git a/src/dialogs/sp-attribute-widget.h b/src/dialogs/sp-attribute-widget.h index dc27c5a24..01da29bed 100644 --- a/src/dialogs/sp-attribute-widget.h +++ b/src/dialogs/sp-attribute-widget.h @@ -1,12 +1,7 @@ -#ifndef __SP_ATTRIBUTE_WIDGET_H__ -#define __SP_ATTRIBUTE_WIDGET_H__ - -/** - * \brief SPAttributeWidget - * - * Widget, that listens and modifies repr attributes - * - * Authors: +/** @file + * @brief Widget that listens and modifies repr attributes + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * * Copyright (C) 2002 authors @@ -15,8 +10,10 @@ * Licensed under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> +#ifndef SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H +#define SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H +#include <glib.h> #include <sigc++/connection.h> #define SP_TYPE_ATTRIBUTE_WIDGET (sp_attribute_widget_get_type ()) @@ -119,7 +116,6 @@ void sp_attribute_table_set_repr ( SPAttributeTable *spw, const gchar **labels, const gchar **attrs ); - #endif /* diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp index c7173ad1e..b0375f755 100644 --- a/src/dialogs/stroke-style.cpp +++ b/src/dialogs/stroke-style.cpp @@ -1,9 +1,7 @@ -#define __SP_STROKE_STYLE_C__ - -/** - * \brief Stroke style dialog - * - * Authors: +/** @file + * @brief Stroke style dialog + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * Bryce Harrington <brycehar@bryceharrington.org> * bulia byak <buliabyak@users.sf.net> @@ -20,12 +18,6 @@ #define noSP_SS_VERBOSE -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - - #include <glib/gmem.h> #include <gtk/gtk.h> @@ -594,7 +586,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, // Find object's bbox in document Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object))); - boost::optional<Geom::Rect> dbox = SP_ITEM(object)->getBounds(i2doc); + Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc); if (!dbox) { return NULL; @@ -1834,7 +1826,6 @@ ink_extract_marker_name(gchar const *n, SPDocument *doc) return marker; } - /* Local Variables: mode:c++ @@ -1844,4 +1835,4 @@ ink_extract_marker_name(gchar const *n, SPDocument *doc) fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/stroke-style.h b/src/dialogs/stroke-style.h index 475a2d388..b947209e3 100644 --- a/src/dialogs/stroke-style.h +++ b/src/dialogs/stroke-style.h @@ -1,16 +1,16 @@ -#ifndef __SP_STROKE_STYLE_H__ -#define __SP_STROKE_STYLE_H__ - -/** - * \brief Stroke style dialog - * - * Author: +/** @file + * @brief Stroke style dialog + */ +/* Author: * Lauris Kaplinski <lauris@ximian.com> * * Copyright (C) 2001 Ximian, Inc. - * + * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_DIALOGS_STROKE_STYLE_H +#define SEEN_DIALOGS_STROKE_STYLE_H + #include <glib.h> #include <gtk/gtkwidget.h> diff --git a/src/dialogs/swatches.cpp b/src/dialogs/swatches.cpp index 71c16d87a..2eb30f27c 100644 --- a/src/dialogs/swatches.cpp +++ b/src/dialogs/swatches.cpp @@ -1,7 +1,7 @@ -/* - * A simple panel for color swatches - * - * Authors: +/** @file + * @brief Color swatches dialog + */ +/* Authors: * Jon A. Cruz * John Bintz * @@ -10,9 +10,6 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif #include <errno.h> diff --git a/src/dialogs/swatches.h b/src/dialogs/swatches.h index 630fada7c..fc3c772b8 100644 --- a/src/dialogs/swatches.h +++ b/src/dialogs/swatches.h @@ -1,16 +1,14 @@ - -#ifndef SEEN_SWATCHES_H -#define SEEN_SWATCHES_H -/* - * A simple dialog for previewing icon representation. - * - * Authors: +/** @file + * @brief Color swatches dialog + */ +/* Authors: * Jon A. Cruz * * Copyright (C) 2005 Jon A. Cruz - * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_DIALOGS_SWATCHES_H +#define SEEN_DIALOGS_SWATCHES_H #include <gtkmm/textview.h> #include <gtkmm/tooltips.h> diff --git a/src/dialogs/text-edit.cpp b/src/dialogs/text-edit.cpp index 1f8395c95..e213a8aba 100644 --- a/src/dialogs/text-edit.cpp +++ b/src/dialogs/text-edit.cpp @@ -1,9 +1,7 @@ -#define __SP_TEXT_EDIT_C__ - -/** - * \brief Text editing dialog - * - * Authors: +/** @file + * @brief Text editing dialog + */ +/* Authors: * Lauris Kaplinski <lauris@ximian.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <goejendaagh@zonnet.nl> @@ -19,7 +17,6 @@ #endif #include <libnrtype/font-instance.h> - #include <gtk/gtk.h> #ifdef WITH_GTKSPELL diff --git a/src/dialogs/text-edit.h b/src/dialogs/text-edit.h index 1fa60c457..1e5cdc77d 100644 --- a/src/dialogs/text-edit.h +++ b/src/dialogs/text-edit.h @@ -1,12 +1,18 @@ -#ifndef SP_TEXT_EDIT_H -#define SP_TEXT_EDIT_H - -/** - * \brief text-edit +/** @file + * @brief Text-edit + */ +/* Authors: + * Lauris Kaplinski <lauris@ximian.com> + * bulia byak <buliabyak@users.sf.net> + * Johan Engelen <goejendaagh@zonnet.nl> * - * Text editing and font changes + * Copyright (C) 1999-2007 Authors + * Copyright (C) 2000-2001 Ximian, Inc. * + * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_DIALOGS_TEXT_EDIT_H +#define SEEN_DIALOGS_TEXT_EDIT_H void sp_text_edit_dialog (void); void sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace trough a verb diff --git a/src/dialogs/unclump.cpp b/src/dialogs/unclump.cpp index 1329fdb5f..2190bf77e 100644 --- a/src/dialogs/unclump.cpp +++ b/src/dialogs/unclump.cpp @@ -1,16 +1,13 @@ -#define __UNCLUMP_C__ - -/* - * Unclumping objects - * - * Authors: +/** @file + * @brief Unclumping objects + */ +/* Authors: * bulia byak * * Copyright (C) 2005 Authors - * Released under GNU GPL + * Released under GNU GPL, read the file 'COPYING' for more information */ - #include <algorithm> #include <map> #include "libnr/nr-matrix-ops.h" @@ -35,7 +32,7 @@ unclump_center (SPItem *item) return i->second; } - boost::optional<Geom::Rect> r = item->getBounds(sp_item_i2d_affine(item)); + Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item)); if (r) { Geom::Point const c = r->midpoint(); c_cache[SP_OBJECT_ID(item)] = c; @@ -54,7 +51,7 @@ unclump_wh (SPItem *item) if ( i != wh_cache.end() ) { wh = i->second; } else { - boost::optional<Geom::Rect> r = item->getBounds(sp_item_i2d_affine(item)); + Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item)); if (r) { wh = r->dimensions(); wh_cache[SP_OBJECT_ID(item)] = wh; @@ -379,3 +376,14 @@ unclump (GSList *items) } } } + +/* + 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/dialogs/unclump.h b/src/dialogs/unclump.h index 6cebc0caf..c5a8bf7d7 100644 --- a/src/dialogs/unclump.h +++ b/src/dialogs/unclump.h @@ -1,20 +1,29 @@ -#ifndef UNCLUMP_H_SEEN -#define UNCLUMP_H_SEEN - -/** \file - * Unclumping objects +/** @file + * @brief Unclumping objects */ -/* - * Authors: +/* Authors: * bulia byak * * Copyright (C) 2005 Authors - * Released under GNU GPL + * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_DIALOGS_UNCLUMP_H +#define SEEN_DIALOGS_UNCLUMP_H + #include <glib/gslist.h> void unclump(GSList *items); - #endif /* !UNCLUMP_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 : diff --git a/src/dialogs/xml-tree.cpp b/src/dialogs/xml-tree.cpp index 2c596bc0e..78a5aa3a7 100644 --- a/src/dialogs/xml-tree.cpp +++ b/src/dialogs/xml-tree.cpp @@ -1,36 +1,18 @@ -#define __SP_XMLVIEW_TREE_C__ - -/** - * \brief XML View - * - * Authors: +/** @file + * @brief XML editor + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * MenTaLguY <mental@rydia.net> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <goejendaagh@zonnet.nl> + * David Turner * * Copyright (C) 1999-2006 Authors - * Copyright (C) 2004 David Turner - * * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <gtk/gtkmain.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkhpaned.h> -#include <gtk/gtkvpaned.h> -#include <gtk/gtkhseparator.h> -#include <gtk/gtkhbbox.h> -#include <gtk/gtktoolbar.h> -#include <gtk/gtkscrolledwindow.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkarrow.h> - +#include <gtk/gtk.h> #include <glibmm/i18n.h> #include "helper/window.h" #include "macros.h" diff --git a/src/dialogs/xml-tree.h b/src/dialogs/xml-tree.h index 6d0d44a7d..0edea8f4d 100644 --- a/src/dialogs/xml-tree.h +++ b/src/dialogs/xml-tree.h @@ -1,10 +1,7 @@ -#ifndef SP_XML_TREE_H -#define SP_XML_TREE_H - -/** - * \brief XML tree editing dialog for Inkscape - * - * Copyright Lauris Kaplinski, 2000 +/** @file + * @brief XML tree editing dialog for Inkscape + */ +/* Copyright Lauris Kaplinski, 2000 * * Released under GNU General Public License. * @@ -13,6 +10,9 @@ * */ +#ifndef SEEN_DIALOGS_XML_TREE_H +#define SEEN_DIALOGS_XML_TREE_H + void sp_xml_tree_dialog (void); #endif diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 1900ed961..357d67359 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -143,13 +143,19 @@ sp_canvas_bpath_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned cbp->affine = affine; - Geom::Rect bbox = bounds_exact_transformed(cbp->curve->get_pathvector(), affine); - - item->x1 = (int)bbox.min()[Geom::X] - 1; - item->y1 = (int)bbox.min()[Geom::Y] - 1; - item->x2 = (int)bbox.max()[Geom::X] + 1; - item->y2 = (int)bbox.max()[Geom::Y] + 1; - + Geom::OptRect bbox = bounds_exact_transformed(cbp->curve->get_pathvector(), affine); + + if (bbox) { + item->x1 = (int)bbox->min()[Geom::X] - 1; + item->y1 = (int)bbox->min()[Geom::Y] - 1; + item->x2 = (int)bbox->max()[Geom::X] + 1; + item->y2 = (int)bbox->max()[Geom::Y] + 1; + } else { + item->x1 = 0; + item->y1 = 0; + item->x2 = 0; + item->y2 = 0; + } sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); } diff --git a/src/display/inkscape-cairo.cpp b/src/display/inkscape-cairo.cpp index 54f979f37..a31a9387f 100644 --- a/src/display/inkscape-cairo.cpp +++ b/src/display/inkscape-cairo.cpp @@ -170,9 +170,9 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path) /** Feeds path-creating calls to the cairo context translating them from the Path, with the given transform and shift */ static void -feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width) +feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, Geom::OptRect area, bool optimize_stroke, double stroke_width) { - if (!area || area->isEmpty()) + if (!area) return; if (path.empty()) return; @@ -214,9 +214,9 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boo /** Feeds path-creating calls to the cairo context translating them from the PathVector, with the given transform and shift * One must have done cairo_new_path(ct); before calling this function. */ void -feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width) +feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, Geom::OptRect area, bool optimize_stroke, double stroke_width) { - if (!area || area->isEmpty()) + if (!area) return; if (pathv.empty()) return; diff --git a/src/display/inkscape-cairo.h b/src/display/inkscape-cairo.h index 4a9c15ae3..cb4d474a6 100644 --- a/src/display/inkscape-cairo.h +++ b/src/display/inkscape-cairo.h @@ -21,7 +21,7 @@ class SPCanvasBuf; cairo_t *nr_create_cairo_context_canvasbuf (NRRectL *area, SPCanvasBuf *b); cairo_t *nr_create_cairo_context (NRRectL *area, NRPixBlock *pb); -void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width); +void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, Geom::OptRect area, bool optimize_stroke, double stroke_width); void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv); #endif diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp index 8b388aa40..d63d9b704 100644 --- a/src/display/nr-arena-group.cpp +++ b/src/display/nr-arena-group.cpp @@ -20,7 +20,7 @@ #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-gaussian-blur.h" -#include "sp-feblend.h" +#include "filters/blend.h" #include "display/nr-filter-blend.h" #include "libnr/nr-matrix-fns.h" #include "libnr/nr-matrix-ops.h" diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 17c9ab07c..3778dc642 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -24,7 +24,7 @@ #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-gaussian-blur.h" -#include "sp-feblend.h" +#include "filters/blend.h" #include "display/nr-filter-blend.h" int nr_arena_image_x_sample = 1; diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index d944b4228..b4fada749 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -255,9 +255,7 @@ nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc, item->ctm = childgc.transform; /* Invoke the real method */ - item->state = - NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state, - reset); + item->state = NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state, reset); if (item->state & NR_ARENA_ITEM_STATE_INVALID) return item->state; /* Enlarge the bounding box to contain filter effects */ @@ -838,12 +836,12 @@ nr_arena_item_set_order (NRArenaItem *item, int order) } void -nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<Geom::Rect> &bbox) +nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect &bbox) { nr_return_if_fail(item != NULL); nr_return_if_fail(NR_IS_ARENA_ITEM(item)); - if(bbox) item->item_bbox = *bbox; + item->item_bbox = bbox; } /** Returns a background image for use with filter effects. */ diff --git a/src/display/nr-arena-item.h b/src/display/nr-arena-item.h index 9db8d7a40..23dd92a43 100644 --- a/src/display/nr-arena-item.h +++ b/src/display/nr-arena-item.h @@ -92,7 +92,7 @@ struct NRArenaItem : public NRObject { NRRectL bbox; /* BBox in item coordinates - this should be a bounding box as * specified in SVG standard. Required by filters. */ - boost::optional<Geom::Rect> item_bbox; + Geom::OptRect item_bbox; /* Our affine */ Geom::Matrix *transform; /* Clip item */ @@ -178,7 +178,7 @@ void nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible); void nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip); void nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask); void nr_arena_item_set_order (NRArenaItem *item, int order); -void nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<Geom::Rect> &bbox); +void nr_arena_item_set_item_bbox (NRArenaItem *item, Geom::OptRect &bbox); NRPixBlock *nr_arena_item_get_background (NRArenaItem const *item, int depth = 0); diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 4c988be46..e47907826 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -229,7 +229,7 @@ nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArena void nr_arena_shape_update_stroke(NRArenaShape *shape, NRGC* gc, NRRectL *area); void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape = false); -void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox); +void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::OptRect &bbox); /** * Updates the arena shape 'item' and all of its children, including the markers. @@ -237,7 +237,7 @@ void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox); static guint nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset) { - Geom::Rect boundingbox; + Geom::OptRect boundingbox; NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -255,10 +255,15 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g if (state & NR_ARENA_ITEM_STATE_BBOX) { if (shape->curve) { boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - item->bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - item->bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - item->bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - item->bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); + /// \todo just write item->bbox = boundingbox + if (boundingbox) { + item->bbox.x0 = (gint32)((*boundingbox)[0][0] - 1.0F); + item->bbox.y0 = (gint32)((*boundingbox)[1][0] - 1.0F); + item->bbox.x1 = (gint32)((*boundingbox)[0][1] + 1.9999F); + item->bbox.y1 = (gint32)((*boundingbox)[1][1] + 1.9999F); + } else { + item->bbox = NR_RECT_L_EMPTY; + } } if (beststate & NR_ARENA_ITEM_STATE_BBOX) { for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { @@ -271,43 +276,44 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g shape->delayed_shp=true; shape->ctm = gc->transform; - boundingbox[0][0] = boundingbox[1][0] = NR_HUGE; - boundingbox[0][1] = boundingbox[1][1] = -NR_HUGE; + boundingbox = Geom::OptRect(); bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); if (shape->curve) { boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE || outline) { + if (boundingbox && (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE || outline)) { float width, scale; scale = gc->transform.descrim(); width = MAX(0.125, shape->_stroke.width * scale); if ( fabs(shape->_stroke.width * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord - boundingbox.expandBy(width); + boundingbox->expandBy(width); } // those pesky miters, now float miterMax=width*shape->_stroke.mitre_limit; if ( miterMax > 0.01 ) { // grunt mode. we should compute the various miters instead (one for each point on the curve) - boundingbox.expandBy(miterMax); + boundingbox->expandBy(miterMax); } } + } + + /// \todo just write item->bbox = boundingbox + if (boundingbox) { + shape->approx_bbox.x0 = (gint32)((*boundingbox)[0][0] - 1.0F); + shape->approx_bbox.y0 = (gint32)((*boundingbox)[1][0] - 1.0F); + shape->approx_bbox.x1 = (gint32)((*boundingbox)[0][1] + 1.9999F); + shape->approx_bbox.y1 = (gint32)((*boundingbox)[1][1] + 1.9999F); } else { + shape->approx_bbox = NR_RECT_L_EMPTY; } - shape->approx_bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - shape->approx_bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - shape->approx_bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - shape->approx_bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); if ( area && nr_rect_l_test_intersect_ptr(area, &shape->approx_bbox) ) shape->delayed_shp=false; /* Release state data */ - if (TRUE || !Geom::transform_equalp(gc->transform, shape->ctm, NR_EPSILON)) { - /* Concept test */ - if (shape->fill_shp) { - delete shape->fill_shp; - shape->fill_shp = NULL; - } + if (shape->fill_shp) { + delete shape->fill_shp; + shape->fill_shp = NULL; } if (shape->stroke_shp) { delete shape->stroke_shp; @@ -339,22 +345,28 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g nr_arena_shape_update_stroke(shape, gc, area); nr_arena_shape_update_fill(shape, gc, area); - boundingbox[0][0] = boundingbox[0][1] = boundingbox[1][0] = boundingbox[1][1] = 0.0; + boundingbox = Geom::OptRect(); nr_arena_shape_add_bboxes(shape, boundingbox); - shape->approx_bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - shape->approx_bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - shape->approx_bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - shape->approx_bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); + /// \todo just write shape->approx_bbox = boundingbox + if (boundingbox) { + shape->approx_bbox.x0 = (gint32)((*boundingbox)[0][0] - 1.0F); + shape->approx_bbox.y0 = (gint32)((*boundingbox)[1][0] - 1.0F); + shape->approx_bbox.x1 = (gint32)((*boundingbox)[0][1] + 1.9999F); + shape->approx_bbox.y1 = (gint32)((*boundingbox)[1][1] + 1.9999F); + } else { + shape->approx_bbox = NR_RECT_L_EMPTY; + } } - if (boundingbox.isEmpty()) + if (!boundingbox) return NR_ARENA_ITEM_STATE_ALL; - item->bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - item->bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - item->bbox.x1 = (gint32)(boundingbox[0][1] + 1.0F); - item->bbox.y1 = (gint32)(boundingbox[1][1] + 1.0F); + /// \todo just write item->bbox = boundingbox + item->bbox.x0 = (gint32)((*boundingbox)[0][0] - 1.0F); + item->bbox.y0 = (gint32)((*boundingbox)[1][0] - 1.0F); + item->bbox.x1 = (gint32)((*boundingbox)[0][1] + 1.0F); + item->bbox.y1 = (gint32)((*boundingbox)[1][1] + 1.0F); nr_arena_request_render_rect(item->arena, &item->bbox); item->render_opacity = TRUE; @@ -442,9 +454,8 @@ void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape) { if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE || force_shape) && -// ((shape->curve->get_length() > 2) || (SP_CURVE_BPATH(shape->curve)[1].code == NR_CURVETO)) ) { // <-- this used to be the old code, i think it has to determine that the path has a sort of 'internal region' where fill would occur has_inner_area(shape->curve->get_pathvector()) ) { - if (TRUE || !shape->fill_shp) { + Geom::Matrix cached_to_new = Geom::identity(); int isometry = 0; if ( shape->cached_fill ) { @@ -522,7 +533,6 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool fo shape->fill_shp->needEdgesSorting(); } shape->delayed_shp |= shape->cached_fpartialy; - } } } @@ -683,7 +693,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) void -nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox) +nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::OptRect &bbox) { /* TODO: are these two if's mutually exclusive? ( i.e. "shape->stroke_shp <=> !shape->fill_shp" ) * if so, then this can be written much more compact ! */ @@ -715,7 +725,7 @@ nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox) // cairo outline rendering: static unsigned int -cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, boost::optional<Geom::Rect> area) +cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, Geom::OptRect area) { NRArenaShape *shape = NR_ARENA_SHAPE(item); diff --git a/src/display/nr-filter-composite.cpp b/src/display/nr-filter-composite.cpp index a1a488674..32fa3e2a5 100644 --- a/src/display/nr-filter-composite.cpp +++ b/src/display/nr-filter-composite.cpp @@ -12,7 +12,7 @@ #include <cmath> #include "2geom/isnan.h" -#include "sp-fecomposite.h" +#include "filters/composite.h" #include "display/nr-filter-composite.h" #include "display/nr-filter-pixops.h" #include "display/nr-filter-slot.h" diff --git a/src/display/nr-filter-composite.h b/src/display/nr-filter-composite.h index e41dd77db..72331f767 100644 --- a/src/display/nr-filter-composite.h +++ b/src/display/nr-filter-composite.h @@ -12,7 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "sp-fecomposite.h" +#include "filters/composite.h" #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h index 669d2c7e1..b3b574f0c 100644 --- a/src/display/nr-filter-diffuselighting.h +++ b/src/display/nr-filter-diffuselighting.h @@ -19,9 +19,9 @@ #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" #include "libnr/nr-matrix.h" -#include "sp-fedistantlight.h" -#include "sp-fepointlight.h" -#include "sp-fespotlight.h" +#include "filters/distantlight.h" +#include "filters/pointlight.h" +#include "filters/spotlight.h" #include "color.h" namespace NR { diff --git a/src/display/nr-filter-displacement-map.h b/src/display/nr-filter-displacement-map.h index 34ba3aad2..6730822d9 100644 --- a/src/display/nr-filter-displacement-map.h +++ b/src/display/nr-filter-displacement-map.h @@ -12,7 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "sp-fedisplacementmap.h" +#include "filters/displacementmap.h" #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 7837770ed..517f2dac9 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -62,7 +62,7 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { Matrix identity(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); - boost::optional<Geom::Rect> area = SVGElem->getBounds(identity); + Geom::OptRect area = SVGElem->getBounds(identity); NRRectL rect; rect.x0=area->min()[NR::X]; diff --git a/src/display/nr-filter-merge.cpp b/src/display/nr-filter-merge.cpp index 1632a7a82..4581238b7 100644 --- a/src/display/nr-filter-merge.cpp +++ b/src/display/nr-filter-merge.cpp @@ -13,7 +13,7 @@ #include <vector> #include "2geom/isnan.h" -#include "sp-femerge.h" +#include "filters/merge.h" #include "display/nr-filter-merge.h" #include "display/nr-filter-pixops.h" #include "display/nr-filter-slot.h" diff --git a/src/display/nr-filter-merge.h b/src/display/nr-filter-merge.h index 5fe6b33e3..3fa62a9cc 100644 --- a/src/display/nr-filter-merge.h +++ b/src/display/nr-filter-merge.h @@ -14,7 +14,7 @@ #include <vector> -#include "sp-femerge.h" +#include "filters/merge.h" #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h index 6de682972..4d0bea8ff 100644 --- a/src/display/nr-filter-specularlighting.h +++ b/src/display/nr-filter-specularlighting.h @@ -19,9 +19,9 @@ #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" #include "libnr/nr-matrix.h" -#include "sp-fedistantlight.h" -#include "sp-fepointlight.h" -#include "sp-fespotlight.h" +#include "filters/distantlight.h" +#include "filters/pointlight.h" +#include "filters/spotlight.h" #include "color.h" namespace NR { diff --git a/src/display/nr-filter-units.h b/src/display/nr-filter-units.h index 49fe30aa9..df38c2bb9 100644 --- a/src/display/nr-filter-units.h +++ b/src/display/nr-filter-units.h @@ -16,6 +16,7 @@ #include "libnr/nr-matrix.h" #include "libnr/nr-rect.h" #include "libnr/nr-rect-l.h" +#include <2geom/rect.h> namespace NR { diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 31aec0748..01a092177 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -136,7 +136,7 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) } Geom::Rect filter_area = filter_effect_area(item_bbox); - if (item_bbox.area() == 0.0) { + if (item_bbox.hasZeroArea()) { // It's no use to try and filter an empty object. return 1; } diff --git a/src/display/nr-light.cpp b/src/display/nr-light.cpp index c2e6f1f83..72ed684b0 100644 --- a/src/display/nr-light.cpp +++ b/src/display/nr-light.cpp @@ -16,9 +16,9 @@ #include "libnr/nr-pixops.h" #include "display/nr-light.h" #include "display/nr-3dutils.h" -#include "sp-fedistantlight.h" -#include "sp-fepointlight.h" -#include "sp-fespotlight.h" +#include "filters/distantlight.h" +#include "filters/pointlight.h" +#include "filters/spotlight.h" namespace NR { diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 02c9a9ea2..723929ea7 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -249,7 +249,7 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, //This glyph has a path description on its d attribute, so we render it: cairo_new_path(cr); Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x); - Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here! (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty boost::optional<Geom::Rect>() ) + Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here! (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty Geom::OptRect() ) feed_pathvector_to_cairo (cr, pathv, s, area, false, 0); cairo_fill(cr); } diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 59578123e..441b64c02 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -15,9 +15,9 @@ #include "desktop.h" #include "desktop-handles.h" -#include "sp-namedview.h" #include "display/sodipodi-ctrl.h" #include "knot.h" +#include "preferences.h" namespace Inkscape { namespace Display { @@ -47,9 +47,10 @@ SnapIndicator::set_new_snappoint(Inkscape::SnappedPoint const p) } */ - SPNamedView *nv = sp_desktop_namedview(_desktop); - - if (nv->snapindicator) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool value = prefs->getBool("/options/snapindicator/value", true); + + if (value) { // TODO add many different kinds of snap indicator :-) // For this we should use p->getTarget() to find out what has snapped // and adjust the shape of the snapindicator accordingly, e.g. a cross diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp index 1bed9355d..c26402743 100644 --- a/src/display/sodipodi-ctrl.cpp +++ b/src/display/sodipodi-ctrl.cpp @@ -12,6 +12,7 @@ #include "sp-canvas-util.h" #include "display-forward.h" #include "sodipodi-ctrl.h" +#include "libnr/nr-pixops.h" enum { ARG_0, @@ -122,6 +123,11 @@ sp_ctrl_destroy (GtkObject *object) ctrl = SP_CTRL (object); + if (ctrl->cache) { + g_free(ctrl->cache); + ctrl->cache = NULL; + } + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -314,11 +320,13 @@ sp_ctrl_build_cache (SPCtrl *ctrl) side = (ctrl->span * 2 +1); c = ctrl->span ; - g_free (ctrl->cache); size = (side) * (side) * 4; - ctrl->cache = (guchar*)g_malloc (size); if (side < 2) return; + if (ctrl->cache) + g_free (ctrl->cache); + ctrl->cache = (guchar*)g_malloc (size); + switch (ctrl->shape) { case SP_CTRL_SHAPE_SQUARE: p = ctrl->cache; @@ -482,9 +490,9 @@ sp_ctrl_build_cache (SPCtrl *ctrl) } // composite background, foreground, alpha for xor mode -#define COMPOSE_X(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) / 0xff ) +#define COMPOSE_X(b,f,a) ( FAST_DIVIDE<255>( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) ) // composite background, foreground, alpha for color mode -#define COMPOSE_N(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) f) * ((guchar) a) ) / 0xff ) +#define COMPOSE_N(b,f,a) ( FAST_DIVIDE<255>( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) f) * ((guchar) a) ) ) static void sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index e9bf1633e..651bd0414 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -795,7 +795,7 @@ sp_canvas_group_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned } } - boost::optional<Geom::Rect> const bounds = corners.bounds(); + Geom::OptRect const bounds = corners.bounds(); if (bounds) { item->x1 = bounds->min()[Geom::X]; item->y1 = bounds->min()[Geom::Y]; @@ -1612,45 +1612,54 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) // Snap when speed drops below e.g. 0.02 px/msec, or when no motion events have occured for some period. // i.e. snap when we're at stand still. A speed threshold enforces snapping for tablets, which might never // be fully at stand still and might keep spitting out motion events. - - if (event->type == GDK_MOTION_NOTIFY) { - Geom::Point event_pos(event->x, event->y); - guint32 event_t = gdk_event_get_time ( (GdkEvent *) event ); - - if (dt) { // put snapping on hold - dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); - } - - if (prev_pos) { - Geom::Coord dist = Geom::L2(event_pos - *prev_pos); - guint32 delta_t = event_t - prev_time; - gdouble speed = delta_t > 0 ? dist/delta_t : 1000; - // std::cout << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " msec" << std::endl; - if (speed > 0.02) { // Jitter threshold, might be needed for tablets - // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. We - // will keep on postponing the snapping as long as the speed is high. - // We must snap at some point in time though, so set a watchdog timer at some time from - // now, just in case there's no future motion event that drops under the speed limit (when - // stoppping abruptly) - sp_canvas_snap_watchdog_kill(canvas); - sp_canvas_snap_watchdog_set(canvas, event); // watchdog is reset, i.e. pushed forward in time - } else { // Speed is very low, so we're virtually at stand still - // But if we're really standing still, then we should snap now. We could use some low-pass filtering, - // otherwise snapping occurs for each jitter movement. For this filtering we'll leave the watchdog to expire, - // snap, and set a new watchdog again. - if (canvas->watchdog_id == 0) { // no watchdog has been set - // it might have already expired, so we'll set a new one; the snapping frequency will be limited by this - sp_canvas_snap_watchdog_set(canvas, event); - } // else: watchdog has been set before and we'll wait for it to expire - } - } else { - // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog - sp_canvas_snap_watchdog_set(canvas, event); - } + if (dt) { + bool const c1 = event->type == GDK_MOTION_NOTIFY; + bool const c21 = event->state & GDK_BUTTON1_MASK; // Snapping only occurs when dragging with the left mouse button down + bool const c22 = event->state & GDK_BUTTON2_MASK; // We shouldn't hold back any events when other mouse buttons have been + bool const c23 = event->state & GDK_BUTTON3_MASK; // pressed, e.g. when scrolling with the middle mouse button; if we do then + // Inkscape will get stuck in an unresponsive state + bool const c3 = dt->namedview->snap_manager.snapprefs.getSnapEnabledGlobally(); + if (c1 && c21 && (!c22) && (!c23) && c3) { + Geom::Point event_pos(event->x, event->y); + guint32 event_t = gdk_event_get_time ( (GdkEvent *) event ); + + dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); // put snapping on hold - prev_pos = event_pos; - prev_time = event_t; - } + if (prev_pos) { + Geom::Coord dist = Geom::L2(event_pos - *prev_pos); + guint32 delta_t = event_t - prev_time; + gdouble speed = delta_t > 0 ? dist/delta_t : 1000; + // std::cout << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " msec" << std::endl; + if (speed > 0.02) { // Jitter threshold, might be needed for tablets + // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. We + // will keep on postponing the snapping as long as the speed is high. + // We must snap at some point in time though, so set a watchdog timer at some time from + // now, just in case there's no future motion event that drops under the speed limit (when + // stoppping abruptly) + sp_canvas_snap_watchdog_kill(canvas); + sp_canvas_snap_watchdog_set(canvas, event); // watchdog is reset, i.e. pushed forward in time + // If the watchdog expires before a new motion event is received, we will snap (as explained + // above). This means however that when the timer is too short, we will always snap and that the + // speed threshold is ineffective. In the extreme case the delay is set to zero, and snapping will + // be immediate, as it used to be in the old days ;-). + } else { // Speed is very low, so we're virtually at stand still + // But if we're really standing still, then we should snap now. We could use some low-pass filtering, + // otherwise snapping occurs for each jitter movement. For this filtering we'll leave the watchdog to expire, + // snap, and set a new watchdog again. + if (canvas->watchdog_id == 0) { // no watchdog has been set + // it might have already expired, so we'll set a new one; the snapping frequency will be limited by this + sp_canvas_snap_watchdog_set(canvas, event); + } // else: watchdog has been set before and we'll wait for it to expire + } + } else { + // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog + sp_canvas_snap_watchdog_set(canvas, event); + } + + prev_pos = event_pos; + prev_time = event_t; + } + } canvas->state = event->state; pick_current_item (canvas, (GdkEvent *) event); @@ -1687,8 +1696,10 @@ gboolean sp_canvas_snap_watchdog_callback(gpointer data) void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + double value = prefs->getDoubleLimited("/options/snapdelay/value", 0, 0, 1000); g_assert(canvas->watchdog_id == 0); - canvas->watchdog_id = g_timeout_add(400, &sp_canvas_snap_watchdog_callback, canvas); + canvas->watchdog_id = g_timeout_add(value, &sp_canvas_snap_watchdog_callback, canvas); g_assert(canvas->watchdog_event == NULL); canvas->watchdog_event = gdk_event_copy( (GdkEvent *) event); } diff --git a/src/document.cpp b/src/document.cpp index 28a2be9a1..d38d5423f 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -560,6 +560,11 @@ gdouble sp_document_height(SPDocument *document) return root->height.computed; } +Geom::Point sp_document_dimensions(SPDocument *doc) +{ + return Geom::Point(sp_document_width(doc), sp_document_height(doc)); +} + /** * Given a Geom::Rect that may, for example, correspond to the bbox of an object, * this function fits the canvas to that rect by resizing the canvas @@ -567,8 +572,6 @@ gdouble sp_document_height(SPDocument *document) */ void SPDocument::fitToRect(Geom::Rect const &rect) { - g_return_if_fail(!rect.isEmpty()); - double const w = rect.width(); double const h = rect.height(); @@ -918,7 +921,7 @@ static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, s = find_items_in_area(s, SP_GROUP(o), dkey, area, test); } else { SPItem *child = SP_ITEM(o); - boost::optional<Geom::Rect> box = sp_item_bbox_desktop(child); + Geom::OptRect box = sp_item_bbox_desktop(child); if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { s = g_slist_append(s, child); } diff --git a/src/document.h b/src/document.h index fff3289dd..99a887c6b 100644 --- a/src/document.h +++ b/src/document.h @@ -21,7 +21,7 @@ #include <sigc++/class_slot.h> #include "libcroco/cr-cascade.h" -#include <2geom/rect.h> +#include <2geom/forward.h> #include "gc-managed.h" #include "gc-finalized.h" @@ -41,10 +41,6 @@ struct SPItem; struct SPObject; struct SPGroup; -namespace Geom { - class Point; -} - namespace Inkscape { struct Application; class Selection; @@ -187,6 +183,7 @@ SPDocument *sp_document_create(Inkscape::XML::Document *rdoc, gchar const *uri, gdouble sp_document_width (SPDocument * document); gdouble sp_document_height (SPDocument * document); +Geom::Point sp_document_dimensions (SPDocument * document); struct SPUnit; diff --git a/src/doxygen-main.cpp b/src/doxygen-main.cpp index 035d83a14..bfca9b21a 100644 --- a/src/doxygen-main.cpp +++ b/src/doxygen-main.cpp @@ -1,15 +1,147 @@ -/** \file - * Contains Doxygen documentation - main page. - * - * Authors: +/** @file + * @brief Doxygen documentation - main page and namespace documentation. + */ +/* Authors: * Ralf Stephan <ralf@ark.in-berlin.de> + * Krzysztof Kosiński <tweenk.pl@gmail.com> * - * Copyright (C) 2005-2006 authors + * Copyright (C) 2005-2008 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ -/** \mainpage The Inkscape Source Code Documentation +// Note: % before a word prevents that word from being linkified + +/** + * @brief Main %Inkscape namespace + * + * This namespace contains all code internal to %Inkscape. + */ +namespace Inkscape { + +/** + * @brief Some STL-style algorithms + * + * This namespace contains a few generic algorithms used with the %XML tree. + */ +namespace Algorithms {} + + +/** + * @brief Debugging utilities + * + * This namespace contains various debugging code which can help developers + * to pinpoint problems with their (or others') code. + */ +namespace Debug {} + +/** + * @brief Rendering-related code + * + * This namespace contains code related to the renderer. + */ +namespace Display {} + +/** + * @brief Extension support + * + * This namespace contains the extension subsystem and implementations + * of the internal extensions. This includes input and output filters, bitmap + * extensions, and printing. + */ +namespace Extension {} + +/** + * @brief Boehm-GC based garbage collector + * + * This namespace contains code related to the garbage collector and base + * classes for %GC-managed objects. + */ +namespace GC {} + +/** + * @brief Low-level IO code + * + * This namespace contains low level IO-related code, including a homegrown + * streams implementation, routines for formatting SVG output, and some + * file handling utility functions. + */ +namespace IO {} + +/** + * @brief Live Path Effects code + * + * This namespace contains classes and functions related to the implementation + * of Live Path Effects, which apply arbitrary transformation to a path and + * update whenever the original path is modified. + */ +namespace LivePathEffect {} + +/** + * @brief Tracing backend + * + * This namespace contains the integrated potrace-based tracing backend, used + * in the Trace Bitmap and Paint Bucket features. + */ +namespace Trace {} + +/** + * @brief User interface code + * + * This namespace contains everything related to the user interface of Inkscape. + */ +namespace UI { + +/** + * @brief Dialog code + * + * This namespace contains all code related to dialogs. + */ +namespace Dialog {} + +/** + * @brief Custom widgets + * + * This namespace contains custom user interface widgets used thorought + * Inkscape. + */ +namespace Widget {} + +} // namespace UI + +/** + * @brief Miscellaneous supporting code + * + * This namespace contains miscellaneous low-level code: an implementation of + * garbage-collected lists, tuples, generic pointer iterators and length unit + * handling. + */ +namespace Util {} + +/** + * @brief %Inkscape %XML tree + * + * This namespace contains classes and functions that comprise the XML tree + * of Inkscape documents. + * + * SVG documents in Inkscape are represented as two parallel hierarchies + * of nodes: the object tree, which contains all information about + * the document's state when loaded, and the %XML tree, which contains all + * information about the document's %XML representation. For this reason + * this tree is also called the "repr tree", and %XML nodes are called "reprs". + * + * The central class is XML::Node, which provides all operations. It should be + * noted that nodes are currently typeless and operations not valid for their + * type simply do nothing (like trying to iterate over children of a text node). + * In addition to standard DOM operations, the %XML tree supports observers - + * objects derived from Xml::NodeObserver which receive notifications about + * changes in the document tree. + */ +namespace XML {} + +} // namespace Inkscape + +/** \mainpage Inkscape Source Code Documentation * While the standard doxygen documentation can be accessed through the links * in the header, the following documents are additionally available to the * interested reader. @@ -32,23 +164,26 @@ * * \subsection liblinks External documentation on libraries used in inkscape * - * <a href="http://www.gtkmm.org/gtkmm2/docs/">Gtkmm</a> - * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000003.html">atkmm</a> - * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000009.html">gdkmm</a> - * <a href="http://www.gtkmm.org/gtkmm2/docs/reference/html/dir_000007.html">pangomm</a> - * <a href="http://libsigc.sourceforge.net/libsigc1_2/reference/html/modules.html">libsigc++</a> + * C++: + * <a href="http://www.gtkmm.org/documentation.shtml">gtkmm</a> + * <a href="http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/namespaceAtk.html">atkmm</a> + * <a href="http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/namespaceGdk.html">gdkmm</a> + * <a href="http://www.gtkmm.org/docs/glibmm-2.4/docs/reference/html/namespaceGlib.html">glibmm</a> + * <a href="http://www.gtkmm.org/docs/pangomm-1.4/docs/reference/html/namespacePango.html">pangomm</a> + * <a href="http://libsigc.sourceforge.net/libsigc2/docs/index.html">libsigc++</a> + * C: * <a href="http://www.gtk.org/api/">GTK+</a> * <a href="http://developer.gnome.org/doc/API/2.0/gdk-pixbuf/index.html">gdk-pixbuf</a> * <a href="http://developer.gnome.org/doc/API/2.0/gobject/index.html">GObject</a> * <a href="http://developer.gnome.org/doc/API/2.0/atk/index.html">atk</a> * <a href="http://developer.gnome.org/doc/API/2.0/pango/index.html">pango</a> - * <a href="http://developer.gnome.org/doc/API/2.0/gnome-vfs-2.0/">GnomeVFS</a> - * <a href="http://libsigc.sourceforge.net/libsigc2/docs/index.html">libsigc</a> * <a href="http://developer.gnome.org/doc/API/2.0/ORBit/index.html">ORBit</a> * <a href="http://developer.gnome.org/doc/API/2.0/libbonobo/index.html">bonobo</a> * <a href="http://developer.gnome.org/doc/API/2.0/bonobo-activation/index.html">bonobo-activation</a> * <a href="http://xmlsoft.org/XSLT/html/libxslt-lib.html#LIBXSLT-LIB">libxslt</a> * <a href="http://xmlsoft.org/html/index.html">libxml2</a> + * Legacy: + * <a href="http://developer.gnome.org/doc/API/2.0/gnome-vfs-2.0/">GnomeVFS</a> * * \subsection stdlinks External standards documentation * @@ -58,7 +193,7 @@ * <a href="http://www.w3.org/Graphics/SVG/Test/">SVGTest</a> * <a href="http://www.libpng.org/pub/png/">PNG</a> * <a href="http://www.w3.org/TR/xslt">XSLT</a> - * <a href="http://partners.adobe.com/public/developer/ps/index_specs.html">PS</a> + * <a href="http://partners.adobe.com/public/developer/ps/index_specs.html">PostScript</a> * <a href="http://developer.gnome.org/projects/gup/hig/">Gnome-HIG</a> */ diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp index fab6f4dad..465bee16a 100644 --- a/src/eraser-context.cpp +++ b/src/eraser-context.cpp @@ -742,7 +742,7 @@ set_to_accumulated(SPEraserContext *dc) Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc()); SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(dc->repr)); - boost::optional<Geom::Rect> eraserBbox = acid->getBounds(Geom::identity()); + Geom::OptRect eraserBbox = acid->getBounds(Geom::identity()); Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt(); std::vector<SPItem*> remainingItems; GSList* toWorkOn = 0; @@ -764,7 +764,7 @@ set_to_accumulated(SPEraserContext *dc) for (GSList *i = toWorkOn ; i ; i = i->next ) { SPItem *item = SP_ITEM(i->data); if ( eraserMode ) { - boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); + Geom::OptRect bbox = item->getBounds(Geom::identity()); if (bbox && bbox->intersects(*eraserBbox)) { Inkscape::XML::Node* dup = dc->repr->duplicate(xml_doc); dc->repr->parent()->appendChild(dup); diff --git a/src/event-context.cpp b/src/event-context.cpp index be7b2e033..963bf2d7e 100644 --- a/src/event-context.cpp +++ b/src/event-context.cpp @@ -499,7 +499,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, ret = TRUE; } else if (zoom_rb == event->button.button) { zoom_rb = 0; - boost::optional<Geom::Rect> const b = Inkscape::Rubberband::get(desktop)->getRectangle(); + Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); Inkscape::Rubberband::get(desktop)->stop(); if (b && !within_tolerance) { desktop->set_display_area(*b, 10); diff --git a/src/extension/init.cpp b/src/extension/init.cpp index afacbed63..0dba9df8f 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -25,18 +25,12 @@ #include "system.h" #include "db.h" #include "internal/svgz.h" -#include "internal/ps.h" -#ifdef HAVE_CAIRO_PDF -# include "internal/pdf-cairo.h" -#endif #ifdef WIN32 # include "internal/win32.h" # include "internal/emf-win32-inout.h" # include "internal/emf-win32-print.h" #endif -#include "internal/ps-out.h" #ifdef HAVE_CAIRO_PDF -# include "internal/cairo-pdf-out.h" # include "internal/cairo-renderer-pdf-out.h" # include "internal/cairo-png-out.h" # include "internal/cairo-ps-out.h" @@ -52,7 +46,6 @@ #include "internal/odf.h" #include "internal/latex-pstricks-out.h" #include "internal/latex-pstricks.h" -#include "internal/eps-out.h" #include "internal/gdkpixbuf-input.h" #include "internal/bluredge.h" #include "internal/gimpgrad.h" @@ -160,19 +153,12 @@ init() /* TODO: Change to Internal */ Internal::Svg::init(); Internal::Svgz::init(); - //Internal::PsOutput::init(); // disabled, to be deleted, replaced by CairoPsOutput - //Internal::EpsOutput::init(); // disabled, to be deleted, replaced by CairoEpsOutput - Internal::PrintPS::init(); + #ifdef HAVE_CAIRO_PDF - if (prefs->getBool("/options/useoldpdfexporter/value")) { - //g_print ("Using CairoPdfOutput: old pdf exporter\n"); - Internal::CairoPdfOutput::init(); - Internal::PrintCairoPDF::init(); - } else { //g_print ("Using CairoRendererPdfOutput: new pdf exporter\n"); Internal::CairoRendererPdfOutput::init(); Internal::CairoRendererOutput::init(); - } + Internal::CairoPsOutput::init(); Internal::CairoEpsOutput::init(); #endif diff --git a/src/extension/internal/Makefile_insert b/src/extension/internal/Makefile_insert index 1de46034e..ee431ee48 100644 --- a/src/extension/internal/Makefile_insert +++ b/src/extension/internal/Makefile_insert @@ -98,16 +98,8 @@ extension_internal_libinternal_a_SOURCES = \ extension/internal/svg.cpp \ extension/internal/svgz.h \ extension/internal/svgz.cpp \ - extension/internal/ps.h \ - extension/internal/ps.cpp \ - extension/internal/ps-out.h \ - extension/internal/ps-out.cpp \ - extension/internal/pdf-cairo.cpp \ - extension/internal/pdf-cairo.h \ extension/internal/pdf-input-cairo.cpp \ extension/internal/pdf-input-cairo.h \ - extension/internal/cairo-pdf-out.h \ - extension/internal/cairo-pdf-out.cpp \ extension/internal/cairo-ps-out.h \ extension/internal/cairo-ps-out.cpp \ extension/internal/cairo-render-context.h \ @@ -118,8 +110,6 @@ extension_internal_libinternal_a_SOURCES = \ extension/internal/cairo-renderer-pdf-out.cpp \ extension/internal/cairo-png-out.h \ extension/internal/cairo-png-out.cpp \ - extension/internal/eps-out.h \ - extension/internal/eps-out.cpp \ extension/internal/javafx-out.cpp \ extension/internal/javafx-out.h \ extension/internal/gdkpixbuf-input.h \ diff --git a/src/extension/internal/cairo-pdf-out.cpp b/src/extension/internal/cairo-pdf-out.cpp deleted file mode 100644 index ac598b9a0..000000000 --- a/src/extension/internal/cairo-pdf-out.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * A quick hack to use the print output to write out a file. This - * then makes 'save as...' PDF. - * - * Authors: - * Ted Gould <ted@gould.cx> - * Ulf Erikson <ulferikson@users.sf.net> - * - * Copyright (C) 2004-2006 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef HAVE_CAIRO_PDF - -#include "cairo-pdf-out.h" -#include <print.h> -#include "extension/system.h" -#include "extension/print.h" -#include "extension/db.h" -#include "extension/output.h" -#include "display/nr-arena.h" -#include "display/nr-arena-item.h" -#include "sp-path.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -bool -CairoPdfOutput::check (Inkscape::Extension::Extension * module) -{ - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF)) - return FALSE; - - return TRUE; -} - - -static unsigned int -pdf_print_document_to_file(SPDocument *doc, gchar const *filename, unsigned int pdf_level, bool texttopath, bool filtertobitmap) -{ - Inkscape::Extension::Print *mod; - SPPrintContext context; - gchar const *oldconst; - gchar *oldoutput; - unsigned int ret; - - sp_document_ensure_up_to_date(doc); - - mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_CAIRO_PDF); - oldconst = mod->get_param_string("destination"); - oldoutput = g_strdup(oldconst); - mod->set_param_string("destination", (gchar *)filename); - -/* Start */ - context.module = mod; - /* fixme: This has to go into module constructor somehow */ - /* Create new arena */ - const gchar* exportId = mod->get_param_string("exportId"); - bool exportDrawing = mod->get_param_bool("exportDrawing"); - bool exportCanvas = mod->get_param_bool("exportCanvas"); - if (exportId && strcmp(exportId, "")) { - // we want to export the given item only - mod->base = SP_ITEM(doc->getObjectById(exportId)); - if (exportCanvas) - mod->set_param_bool("pageBoundingBox", TRUE); - else - mod->set_param_bool("pageBoundingBox", FALSE); - } else { - // we want to export the entire document from root - mod->base = SP_ITEM(sp_document_root(doc)); - if (exportDrawing) - mod->set_param_bool("pageBoundingBox", FALSE); - else - mod->set_param_bool("pageBoundingBox", TRUE); - } - mod->arena = NRArena::create(); - mod->dkey = sp_item_display_key_new(1); - mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY); - - /* Print document */ - ret = mod->begin(doc); - if (ret) { - sp_item_invoke_print(mod->base, &context); - ret = mod->finish(); - } - - /* Release arena */ - sp_item_invoke_hide(mod->base, mod->dkey); - mod->base = NULL; - mod->root = NULL; - nr_object_unref((NRObject *) mod->arena); - mod->arena = NULL; -/* end */ - - mod->set_param_string("destination", oldoutput); - g_free(oldoutput); - - return ret; -} - - -/** - \brief This function calls the print system with the filename - \param mod unused - \param doc Document to be saved - \param uri Filename to save to (probably will end in .pdf) - - The most interesting thing that this function does is just attach - an '>' on the front of the filename. This is the syntax used to - tell the printing system to save to file. -*/ -void -CairoPdfOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri) -{ - Inkscape::Extension::Extension * ext; - unsigned int ret; - - ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PDF); - if (ext == NULL) - return; - - bool old_textToPath = FALSE; - bool new_textToPath = FALSE; - try { - old_textToPath = ext->get_param_bool("textToPath"); - new_textToPath = mod->get_param_bool("textToPath"); - ext->set_param_bool("textToPath", new_textToPath); - } - catch(...) { - g_warning("Parameter <textToPath> might not exist"); - } - - bool old_blurToBitmap = FALSE; - bool new_blurToBitmap = FALSE; - try { - old_blurToBitmap = ext->get_param_bool("blurToBitmap"); - new_blurToBitmap = mod->get_param_bool("blurToBitmap"); - ext->set_param_bool("blurToBitmap", new_blurToBitmap); - } - catch(...) { - g_warning("Parameter <blurToBitmap> might not exist"); - } - - const gchar* old_exportId = NULL; - const gchar* new_exportId = NULL; - try { - old_exportId = ext->get_param_string("exportId"); - new_exportId = mod->get_param_string("exportId"); - ext->set_param_string("exportId", new_exportId); - } - catch(...) { - g_warning("Parameter <exportId> might not exist"); - } - - bool old_exportDrawing = false; - bool new_exportDrawing = false; - try { - old_exportDrawing = ext->get_param_bool("exportDrawing"); - new_exportDrawing = mod->get_param_bool("exportDrawing"); - ext->set_param_bool("exportDrawing", new_exportDrawing); - } - catch(...) { - g_warning("Parameter <exportDrawing> might not exist"); - } - - bool old_exportCanvas = false; - bool new_exportCanvas = false; - try { - old_exportCanvas = ext->get_param_bool("exportCanvas"); - new_exportCanvas = mod->get_param_bool("exportCanvas"); - ext->set_param_bool("exportCanvas", new_exportCanvas); - } - catch(...) { - g_warning("Parameter <exportCanvas> might not exist"); - } - - gchar * final_name; - final_name = g_strdup_printf("> %s", uri); - ret = pdf_print_document_to_file(doc, final_name, 0, new_textToPath, new_blurToBitmap); - g_free(final_name); - - try { - ext->set_param_bool("blurToBitmap", old_blurToBitmap); - } - catch(...) { - g_warning("Parameter <blurToBitmap> might not exist"); - } - try { - ext->set_param_bool("textToPath", old_textToPath); - } - catch(...) { - g_warning("Parameter <textToPath> might not exist"); - } - try { - ext->set_param_string("exportId", old_exportId); - } - catch(...) { - g_warning("Parameter <exportId> might not exist"); - } - try { - ext->set_param_bool("exportDrawing", old_exportDrawing); - } - catch(...) { - g_warning("Parameter <exportDrawing> might not exist"); - } - try { - ext->set_param_bool("exportCanvas", old_exportCanvas); - } - catch(...) { - g_warning("Parameter <exportCanvas> might not exist"); - } - - if (!ret) - throw Inkscape::Extension::Output::save_failed(); - - return; -} - -#include "clear-n_.h" -/** - \brief A function allocate a copy of this function. - - This is the definition of PDF out. This function just - calls the extension system with the memory allocated XML that - describes the data. -*/ -void -CairoPdfOutput::init (void) -{ - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Cairo PDF Output") "</name>\n" - "<id>org.inkscape.output.pdf.cairo</id>\n" - "<param name=\"PDFversion\" gui-text=\"" N_("Restrict to PDF version") "\" type=\"enum\" >\n" - "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n" - "</param>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n" - "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n" - "<param name=\"exportDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n" - "<param name=\"exportCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n" - "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" - "<output>\n" - "<extension>.pdf</extension>\n" - "<mimetype>application/pdf</mimetype>\n" - "<filetypename>" N_("PDF via Cairo (*.pdf)") "</filetypename>\n" - "<filetypetooltip>" N_("PDF File") "</filetypetooltip>\n" - "</output>\n" - "</inkscape-extension>", new CairoPdfOutput()); - - return; -} - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* HAVE_CAIRO_PDF */ - -/* - 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/extension/internal/cairo-pdf-out.h b/src/extension/internal/cairo-pdf-out.h deleted file mode 100644 index 42cd9365c..000000000 --- a/src/extension/internal/cairo-pdf-out.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * A quick hack to use the print output to write out a file. This - * then makes 'save as...' PDF. - * - * Authors: - * Ted Gould <ted@gould.cx> - * Ulf Erikson <ulferikson@users.sf.net> - * - * Copyright (C) 2004-2006 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef EXTENSION_INTERNAL_CAIRO_PDF_OUT_H -#define EXTENSION_INTERNAL_CAIRO_PDF_OUT_H - -#include "extension/implementation/implementation.h" - -#ifdef HAVE_CAIRO_PDF - -namespace Inkscape { -namespace Extension { -namespace Internal { - -class CairoPdfOutput : Inkscape::Extension::Implementation::Implementation { - -public: - bool check(Inkscape::Extension::Extension *module); - void save(Inkscape::Extension::Output *mod, - SPDocument *doc, - gchar const *uri); - static void init(); -}; - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* HAVE_CAIRO_PDF */ - -#endif /* !EXTENSION_INTERNAL_CAIRO_PDF_OUT_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:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 01afec0fc..e33316c94 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -282,7 +282,7 @@ CairoPsOutput::init (void) "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n" + "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n" "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" "<output>\n" @@ -319,7 +319,7 @@ CairoEpsOutput::init (void) "<param name=\"areaCanvas\" gui-text=\"" N_("Export area is whole canvas") "\" type=\"boolean\">true</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export area is the drawing") "\" type=\"boolean\">true</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">false</param>\n" + "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert blur effects to bitmaps") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n" "<param name=\"exportId\" gui-text=\"" N_("Limit export to the object with ID") "\" type=\"string\"></param>\n" "<output>\n" diff --git a/src/extension/internal/cairo-renderer-pdf-out.cpp b/src/extension/internal/cairo-renderer-pdf-out.cpp index c82cc7611..cb17002d4 100644 --- a/src/extension/internal/cairo-renderer-pdf-out.cpp +++ b/src/extension/internal/cairo-renderer-pdf-out.cpp @@ -216,7 +216,7 @@ CairoRendererPdfOutput::init (void) "<_item value='PDF14'>" N_("PDF 1.4") "</_item>\n" "</param>\n" "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">false</param>\n" - "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert filter effects to bitmaps") "\" type=\"boolean\">false</param>\n" + "<param name=\"blurToBitmap\" gui-text=\"" N_("Convert filter effects to bitmaps") "\" type=\"boolean\">true</param>\n" "<param name=\"resolution\" gui-text=\"" N_("Preferred resolution (DPI) of bitmaps") "\" type=\"int\" min=\"72\" max=\"2400\">90</param>\n" "<param name=\"areaDrawing\" gui-text=\"" N_("Export drawing, not page") "\" type=\"boolean\">false</param>\n" "<param name=\"areaCanvas\" gui-text=\"" N_("Export canvas") "\" type=\"boolean\">false</param>\n" diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 5d6315894..4bc983cb7 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -446,7 +446,7 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) TRACE(("sp_asbitmap_render: resolution: %f\n", res )); // Get the bounding box of the selection in document coordinates. - boost::optional<Geom::Rect> bbox = + Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item), SPItem::RENDERING_BBOX); if (!bbox) // no bbox, e.g. empty group diff --git a/src/extension/internal/eps-out.cpp b/src/extension/internal/eps-out.cpp deleted file mode 100644 index c08bd1de6..000000000 --- a/src/extension/internal/eps-out.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Authors: - * Ted Gould <ted@gould.cx> - * - * Copyright (C) 2004 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "eps-out.h" -#include <print.h> -#include "extension/system.h" -#include "extension/db.h" -#include "extension/output.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -bool -EpsOutput::check (Inkscape::Extension::Extension * module) -{ - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_PS)) - return FALSE; - - return TRUE; -} - -/** - \brief This function calls the print system with the filename - \param mod unused - \param doc Document to be saved - \param uri Filename to save to (probably will end in .eps) - - The most interesting thing that this function does is just attach - an '>' on the front of the filename. This is the syntax used to - tell the printing system to save to file. -*/ -void -EpsOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri) -{ - gchar * final_name; - Inkscape::Extension::Extension * ext; - - ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_PS); - if (ext == NULL) - return; - - bool old_pageBoundingBox = ext->get_param_bool("pageBoundingBox"); - bool new_val = mod->get_param_bool("pageBoundingBox"); - ext->set_param_bool("pageBoundingBox", new_val); - - bool old_textToPath = ext->get_param_bool("textToPath"); - new_val = mod->get_param_bool("textToPath"); - ext->set_param_bool("textToPath", new_val); - - bool old_fontEmbedded = ext->get_param_bool("fontEmbedded"); - new_val = mod->get_param_bool("fontEmbedded"); - ext->set_param_bool("fontEmbedded", new_val); - - final_name = g_strdup_printf("> %s", uri); - sp_print_document_to_file(doc, final_name); - g_free(final_name); - - ext->set_param_bool("pageBoundingBox", old_pageBoundingBox); - ext->set_param_bool("textToPath", old_textToPath); - ext->set_param_bool("fontEmbedded", old_fontEmbedded); - - return; -} - -#include "clear-n_.h" - -/** - \brief A function allocate a copy of this function. - - This is the definition of postscript out. This function just - calls the extension system with the memory allocated XML that - describes the data. -*/ -void -EpsOutput::init (void) -{ - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Encapsulated Postscript Output") "</name>\n" - "<id>org.inkscape.output.eps</id>\n" - "<param name=\"pageBoundingBox\" type=\"boolean\" gui-text=\"" N_("Make bounding box around full page") "\">false</param>\n" - "<param name=\"textToPath\" type=\"boolean\" gui-text=\"" N_("Convert texts to paths") "\">true</param>\n" - "<param name=\"fontEmbedded\" type=\"boolean\" gui-text=\"" N_("Embed fonts (Type 1 only)") "\">false</param>\n" - "<output>\n" - "<extension>.eps</extension>\n" - "<mimetype>image/x-eps</mimetype>\n" - "<filetypename>" N_("Encapsulated Postscript (*.eps)") "</filetypename>\n" - "<filetypetooltip>" N_("Encapsulated Postscript File") "</filetypetooltip>\n" - "</output>\n" - "</inkscape-extension>", new EpsOutput()); - - return; -} - -} } } /* namespace Inkscape, Extension, Implementation */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/extension/internal/eps-out.h b/src/extension/internal/eps-out.h deleted file mode 100644 index 41a6c1f5c..000000000 --- a/src/extension/internal/eps-out.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Authors: - * Ted Gould <ted@gould.cx> - * - * Copyright (C) 2004 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef EXTENSION_INTERNAL_EPS_OUT_H -#define EXTENSION_INTERNAL_EPS_OUT_H - -#include <gtk/gtkdialog.h> -#include <gtk/gtkwidget.h> - -#include "extension/implementation/implementation.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -class EpsOutput : Inkscape::Extension::Implementation::Implementation { -public: - bool check(Inkscape::Extension::Extension *module); - - void save(Inkscape::Extension::Output *mod, - SPDocument *doc, - gchar const *uri); - - static void init(void); -}; - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* EXTENSION_INTERNAL_EPS_OUT_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/extension/internal/filter/drop-shadow.h b/src/extension/internal/filter/drop-shadow.h index e0785df30..4a02086e2 100644 --- a/src/extension/internal/filter/drop-shadow.h +++ b/src/extension/internal/filter/drop-shadow.h @@ -41,7 +41,9 @@ public: "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" - "<submenu name=\"" N_("Filter") "\" />\n" + "<submenu name=\"" N_("Filters") "\" >\n" + "<submenu name=\"Shadows and Glows\"/>\n" + "</submenu>\n" "</effects-menu>\n" "<menu-tip>" N_("Black, blurred drop shadow") "</menu-tip>\n" "</effect>\n" @@ -61,7 +63,7 @@ DropShadow::get_filter_text (Inkscape::Extension::Extension * ext) float y = ext->get_param_float("yoffset"); _filter = g_strdup_printf( - "<filter>\n" + "<filter width=\"1.5\" height=\"1.5\" x=\"-.25\" y=\"-.25\">\n" "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%f\" result=\"blur\"/>\n" "<feColorMatrix result=\"bluralpha\" type=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %f 0 \" />\n" "<feOffset in=\"bluralpha\" dx=\"%f\" dy=\"%f\" result=\"offsetBlur\"/>\n" @@ -74,6 +76,61 @@ DropShadow::get_filter_text (Inkscape::Extension::Extension * ext) return _filter; }; +class DropGlow : public Inkscape::Extension::Internal::Filter::Filter { +protected: + virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext); + +public: + DropGlow ( ) : Filter() { }; + virtual ~DropGlow ( ) { if (_filter != NULL) g_free((void *)_filter); return; } + + static void init (void) { + Inkscape::Extension::build_from_mem( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>" N_("Drop Glow") "</name>\n" + "<id>org.inkscape.effect.filter.drop-glow</id>\n" + "<param name=\"blur\" gui-text=\"" N_("Blur radius, px") "\" type=\"float\" min=\"0.0\" max=\"200.0\">2.0</param>\n" + "<param name=\"opacity\" gui-text=\"" N_("Opacity, %") "\" type=\"float\" min=\"0.0\" max=\"100.0\">50</param>\n" + "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset, px") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset, px") "\" type=\"float\" min=\"-50.0\" max=\"50.0\">4.0</param>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"Shadows and Glows\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>" N_("White, blurred drop glow") "</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", new DropGlow()); + }; + +}; + +gchar const * +DropGlow::get_filter_text (Inkscape::Extension::Extension * ext) +{ + if (_filter != NULL) g_free((void *)_filter); + + float blur = ext->get_param_float("blur"); + float opacity = ext->get_param_float("opacity") / 100; + float x = ext->get_param_float("xoffset"); + float y = ext->get_param_float("yoffset"); + + _filter = g_strdup_printf( + "<filter width=\"1.5\" height=\"1.5\" x=\"-.25\" y=\"-.25\">\n" + "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%f\" result=\"blur\"/>\n" + "<feColorMatrix result=\"bluralpha\" type=\"matrix\" values=\"-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 %f 0 \" />\n" + "<feOffset in=\"bluralpha\" dx=\"%f\" dy=\"%f\" result=\"offsetBlur\"/>\n" + "<feMerge>\n" + "<feMergeNode in=\"offsetBlur\"/>\n" + "<feMergeNode in=\"SourceGraphic\"/>\n" + "</feMerge>\n" + "</filter>\n", blur, opacity, x, y); + + return _filter; +}; + }; /* namespace Filter */ }; /* namespace Internal */ }; /* namespace Extension */ diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp index 6f0208a0b..b4b8caf81 100644 --- a/src/extension/internal/filter/filter-all.cpp +++ b/src/extension/internal/filter/filter-all.cpp @@ -8,34 +8,8 @@ #include "filter.h" /* Put your filter here */ -#include "apparition.h" -#include "bloom.h" -#include "clouds.h" -#include "crystal.h" -#include "cutout.h" #include "drop-shadow.h" -#include "emboss.h" -#include "etched-glass.h" -#include "fire.h" -#include "frost.h" -#include "ink-bleed.h" -#include "jelly-bean.h" -#include "jigsaw-piece.h" -#include "leopard-fur.h" -#include "melt.h" -#include "metal.h" -#include "motion-blur.h" -#include "oil-slick.h" -#include "patterned-glass.h" -#include "ridged-border.h" -#include "ripple.h" -#include "roughen.h" -#include "rubber-stamp.h" -#include "sepia.h" #include "snow.h" -#include "speckle.h" -#include "zebra.h" - namespace Inkscape { namespace Extension { @@ -46,35 +20,13 @@ namespace Filter { void Filter::filters_all (void ) { - Apparition::init(); - Bloom::init(); - Clouds::init(); - Crystal::init(); - Cutout::init(); + // Here come the filters which are coded in C++ in order to present a parameters dialog DropShadow::init(); - Emboss::init(); - EtchedGlass::init(); - Fire::init(); - Frost::init(); - InkBleed::init(); - JellyBean::init(); - JigsawPiece::init(); - LeopardFur::init(); - Melt::init(); - Metal::init(); - MotionBlur::init(); - OilSlick::init(); - PatternedGlass::init(); - RidgedBorder::init(); - Ripple::init(); - Roughen::init(); - RubberStamp::init(); - Sepia::init(); + DropGlow::init(); Snow::init(); - Speckle::init(); - Zebra::init(); - + // Here come the rest of the filters that are read from SVG files in share/filters and + // .config/Inkscape/filters /* This should always be last, don't put stuff below this * line. */ Filter::filters_all_files(); diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp index 857c01a1c..7cb671f51 100644 --- a/src/extension/internal/filter/filter-file.cpp +++ b/src/extension/internal/filter/filter-file.cpp @@ -130,6 +130,8 @@ void Filter::filters_load_node (Inkscape::XML::Node * node, gchar * menuname) { gchar const * label = node->attribute("inkscape:label"); + gchar const * menu = node->attribute("inkscape:menu"); + gchar const * menu_tooltip = node->attribute("inkscape:menu-tooltip"); gchar const * id = node->attribute("id"); if (label == NULL) { @@ -143,12 +145,18 @@ Filter::filters_load_node (Inkscape::XML::Node * node, gchar * menuname) "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" - "<submenu name=\"" N_("Filter") "\">\n" - "<submenu name=\"%s\"/>\n" - "</submenu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"%s\"/>\n" + "</submenu>\n" "</effects-menu>\n" + "<menu-tip>%s</menu-tip>\n" "</effect>\n" - "</inkscape-extension>\n", label, id, menuname); + "</inkscape-extension>\n", label, id, menu? menu : menuname, menu_tooltip? menu_tooltip : label); + + // FIXME: Bad hack: since we pull out a single filter node out of SVG file and + // serialize it, it loses the namespace declarations from the root, so we must provide + // one right here for our inkscape attributes + node->setAttribute("xmlns:inkscape", SP_INKSCAPE_NS_URI); mywriter writer; sp_repr_write_stream(node, writer, 0, FALSE, g_quark_from_static_string("svg"), 0, 0); diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 1ba0ce8ca..5a104b6a1 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -109,8 +109,6 @@ Filter::merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Ink } Inkscape::GC::release(to_child); } - - return; } #define FILTER_SRC_GRAPHIC "fbSourceGraphic" @@ -139,8 +137,10 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d gchar const * filter = sp_repr_css_property(css, "filter", NULL); if (filter == NULL) { + Inkscape::XML::Node * newfilterroot = xmldoc->createElement("svg:filter"); defsrepr->appendChild(newfilterroot); + Glib::ustring url = "url(#"; url += newfilterroot->attribute("id"); url += ")"; merge_filters(newfilterroot, get_filter(module)->root(), xmldoc); @@ -189,7 +189,7 @@ Filter::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *d #include "extension/internal/clear-n_.h" void -Filter::filter_init (gchar const * id, gchar const * name, gchar const * tip, gchar const * filter) +Filter::filter_init (gchar const * id, gchar const * name, gchar const * submenu, gchar const * tip, gchar const * filter) { gchar * xml_str = g_strdup_printf( "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" @@ -198,11 +198,12 @@ Filter::filter_init (gchar const * id, gchar const * name, gchar const * tip, gc "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" - "<submenu name=\"" N_("Filter") "\" />\n" + "<submenu name=\"" N_("Filters") "\" />\n" + "<submenu name=\"%s\"/>\n" "</effects-menu>\n" "<menu-tip>%s</menu-tip>\n" "</effect>\n" - "</inkscape-extension>\n", name, id, tip); + "</inkscape-extension>\n", name, id, submenu, tip); Inkscape::Extension::build_from_mem(xml_str, new Filter::Filter(filter)); g_free(xml_str); return; diff --git a/src/extension/internal/filter/filter.h b/src/extension/internal/filter/filter.h index 05fdcc4cd..fe6b678d9 100644 --- a/src/extension/internal/filter/filter.h +++ b/src/extension/internal/filter/filter.h @@ -36,7 +36,7 @@ public: Inkscape::Extension::Implementation::ImplementationDocumentCache * newDocCache (Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * doc); void effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache); - static void filter_init(gchar const * id, gchar const * name, gchar const * tip, gchar const * filter); + static void filter_init(gchar const * id, gchar const * name, gchar const * submenu, gchar const * tip, gchar const * filter); static void filters_all(void); /* File loader related */ diff --git a/src/extension/internal/filter/snow.h b/src/extension/internal/filter/snow.h index 366bdcf1f..cf5065754 100644 --- a/src/extension/internal/filter/snow.h +++ b/src/extension/internal/filter/snow.h @@ -35,9 +35,11 @@ public: "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" - "<submenu name=\"" N_("Filter") "\" />\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"Shadows and Glows\"/>\n" + "</submenu>\n" "</effects-menu>\n" - "<menu-tip>" N_("When the weather outside is frightening...") "</menu-tip>\n" + "<menu-tip>" N_("Snow has fallen on object") "</menu-tip>\n" "</effect>\n" "</inkscape-extension>\n", new Snow()); }; diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index 366bab000..d4b35b261 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -85,7 +85,7 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc bounding_area = Geom::Rect( Geom::Point(0,0), Geom::Point(sp_document_width(doc), sp_document_height(doc)) ); } else { - boost::optional<Geom::Rect> bounds = selection->bounds(); + Geom::OptRect bounds = selection->bounds(); if (bounds) { bounding_area = *bounds; } diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index 967ddd92d..69ee296e5 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -187,6 +187,16 @@ static JavaFXOutput::String getStrokeLineJoin(unsigned value) { }
+/**
+ * Replace illegal characters for JavaFX for a underscore.
+ */
+static JavaFXOutput::String sanatize(const JavaFXOutput::String &badstr){
+ JavaFXOutput::String good(badstr);
+ for (int pos = 0; pos < badstr.length(); ++pos )
+ if((badstr.at(pos)=='-')||(badstr.at(pos)==' '))
+ good.replace(pos, 1, "_");
+ return good;
+}
/**
* Output data to the buffer, printf()-style
@@ -298,11 +308,13 @@ bool JavaFXOutput::doTail() */
bool JavaFXOutput::doGradient(SPGradient *grad, const String &id)
{
+ String jfxid = sanatize(id);
+
if (SP_IS_LINEARGRADIENT(grad))
{
SPLinearGradient *g = SP_LINEARGRADIENT(grad);
- out(" /* create LinearGradient for %s */\n", id.c_str());
- out(" private function %s(): LinearGradient {\n", id.c_str());
+ out(" /* create LinearGradient for %s */\n", jfxid.c_str());
+ out(" private function %s(): LinearGradient {\n", jfxid.c_str());
out(" LinearGradient {\n");
std::vector<SPGradientStop> stops = g->vector.stops;
if (stops.size() > 0)
@@ -320,14 +332,14 @@ bool JavaFXOutput::doGradient(SPGradient *grad, const String &id) out(" ]\n");
}
out(" };\n");
- out(" } // end LinearGradient: %s\n", id.c_str());
+ out(" } // end LinearGradient: %s\n", jfxid.c_str());
out("\n\n");
}
else if (SP_IS_RADIALGRADIENT(grad))
{
SPRadialGradient *g = SP_RADIALGRADIENT(grad);
- out(" /* create RadialGradient for %s */\n", id.c_str());
- out(" private function %s() {\n", id.c_str());
+ out(" /* create RadialGradient for %s */\n", jfxid.c_str());
+ out(" private function %s() {\n", jfxid.c_str());
out(" RadialGradient {\n");
out(" centerX: %s\n", DSTR(g->cx.value));
out(" centerY: %s\n", DSTR(g->cy.value));
@@ -350,12 +362,12 @@ bool JavaFXOutput::doGradient(SPGradient *grad, const String &id) out(" ]\n");
}
out(" };\n");
- out(" } // end RadialGradient: %s\n", id.c_str());
+ out(" } // end RadialGradient: %s\n", jfxid.c_str());
out("\n\n");
}
else
{
- err("Unknown gradient type for '%s'\n", id.c_str());
+ err("Unknown gradient type for '%s'\n", jfxid.c_str());
return false;
}
@@ -392,7 +404,7 @@ bool JavaFXOutput::doStyle(SPStyle *style) /* trim the anchor '#' from the front */
if (uri.size() > 0 && uri[0]=='#')
uri = uri.substr(1);
- out(" fill: %s()\n", uri.c_str());
+ out(" fill: %s()\n", sanatize(uri).c_str());
}
}
@@ -456,6 +468,8 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id) using Geom::X;
using Geom::Y;
+ String jfxid = sanatize(id);
+
//### Get the Shape
if (!SP_IS_SHAPE(item))//Bulia's suggestion. Allow all shapes
return true;
@@ -467,10 +481,10 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id) nrShapes++;
- out(" /** path %s */\n", id.c_str());
- out(" private function %s() : Path {\n",id.c_str());
+ out(" /** path %s */\n", jfxid.c_str());
+ out(" private function %s() : Path {\n",jfxid.c_str());
out(" Path {\n");
- out(" id: \"%s\"\n", id.c_str());
+ out(" id: \"%s\"\n", jfxid.c_str());
/**
* Output the style information
@@ -560,7 +574,7 @@ bool JavaFXOutput::doCurve(SPItem *item, const String &id) out(" ] // elements\n");
out(" }; // Path\n");
- out(" } // end path %s\n\n", id.c_str());
+ out(" } // end path %s\n\n", jfxid.c_str());
double cminx = cminmax.min()[X];
double cmaxx = cminmax.max()[X];
@@ -737,7 +751,8 @@ bool JavaFXOutput::doTree(SPDocument *doc) }
-bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj) {
+bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj)
+{
/**
* Check the type of node and process
*/
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 2e0082832..c15b839d7 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -962,10 +962,10 @@ static Geom::Matrix getODFTransform(const SPItem *item) * Get the bounding box of an item, as mapped onto * an ODF document, in cm. */ -static boost::optional<Geom::Rect> getODFBoundingBox(const SPItem *item) +static Geom::OptRect getODFBoundingBox(const SPItem *item) { - boost::optional<Geom::Rect> bbox_temp = sp_item_bbox_desktop((SPItem *)item); - boost::optional<Geom::Rect> bbox; + Geom::OptRect bbox_temp = sp_item_bbox_desktop((SPItem *)item); + Geom::OptRect bbox; if (bbox_temp) { bbox = *bbox_temp; double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT); @@ -1866,7 +1866,7 @@ bool OdfOutput::writeTree(Writer &couts, Writer &souts, Geom::Matrix tf = getODFTransform(item); //### Get ODF bounding box params for item - boost::optional<Geom::Rect> bbox = getODFBoundingBox(item); + Geom::OptRect bbox = getODFBoundingBox(item); if (!bbox) { return true; } diff --git a/src/extension/internal/pdf-cairo.cpp b/src/extension/internal/pdf-cairo.cpp deleted file mode 100644 index 6c2b2ed62..000000000 --- a/src/extension/internal/pdf-cairo.cpp +++ /dev/null @@ -1,1060 +0,0 @@ -#define __SP_PDF_CAIRO_C__ - -/** \file - * PDF printing with Cairo. - */ -/* - * Authors: - * Miklós Erdélyi <erdelyim@gmail.com> - * - * Based on pdf.cpp - * - * Licensed under GNU GPL - */ - -/* Plain Print */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_CAIRO_PDF - -#ifndef PANGO_ENABLE_BACKEND -#define PANGO_ENABLE_BACKEND -#endif - -#ifndef PANGO_ENABLE_ENGINE -#define PANGO_ENABLE_ENGINE -#endif - - -#include <signal.h> -#include <errno.h> - -#include <glib/gmem.h> -#include <gtk/gtkstock.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkframe.h> -#include <gtk/gtkradiobutton.h> -#include <gtk/gtkcombo.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkentry.h> -#include <gtk/gtktooltips.h> - -#include <glibmm/i18n.h> -#include "display/nr-arena-item.h" -#include "display/canvas-bpath.h" -#include "display/inkscape-cairo.h" -#include "sp-item.h" -#include "style.h" -#include "sp-linear-gradient.h" -#include "sp-radial-gradient.h" - -#include "libnrtype/font-instance.h" -#include "libnrtype/font-style-to-pos.h" - -#include "libnr/nr-matrix.h" -#include "libnr/nr-matrix-fns.h" -#include "libnr/nr-matrix-ops.h" - -#include <unit-constants.h> - -#include "pdf-cairo.h" -#include "extension/system.h" -#include "extension/print.h" - -#include "io/sys.h" - -#include <cairo.h> -#include <cairo-pdf.h> - -#include <pango/pango.h> -#include <pango/pangofc-fontmap.h> - -#ifdef RENDER_WITH_PANGO_CAIRO -#include <pango/pangocairo.h> -#else -#include <cairo-ft.h> -#endif -namespace Inkscape { -namespace Extension { -namespace Internal { - -static cairo_status_t _write_callback(void *closure, const unsigned char *data, unsigned int length); -static void _concat_transform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0); - -PrintCairoPDF::PrintCairoPDF() : - cr(NULL), - pdf_surface(NULL), - _layout(NULL), - _dpi(72), - _bitmap(false) -{ -} - -PrintCairoPDF::~PrintCairoPDF(void) -{ - if (cr) cairo_destroy(cr); - if (pdf_surface) cairo_surface_destroy(pdf_surface); - if (_layout) g_object_unref(_layout); - - /* restore default signal handling for SIGPIPE */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_DFL); -#endif - - return; -} - -unsigned int -PrintCairoPDF::setup(Inkscape::Extension::Print * mod) -{ - static gchar const *const pdr[] = {"72", "75", "100", "144", "150", "200", "300", "360", "600", "1200", "2400", NULL}; - -#ifdef TED - Inkscape::XML::Node *repr = ((SPModule *) mod)->repr; -#endif - - unsigned int ret = FALSE; - - /* Create dialog */ - GtkTooltips *tt = gtk_tooltips_new(); - g_object_ref((GObject *) tt); - gtk_object_sink((GtkObject *) tt); - - GtkWidget *dlg = gtk_dialog_new_with_buttons(_("Print Destination"), -// SP_DT_WIDGET(SP_ACTIVE_DESKTOP)->window, - NULL, - (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - GTK_STOCK_PRINT, - GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_default_response(GTK_DIALOG(dlg), GTK_RESPONSE_OK); - - GtkWidget *vbox = GTK_DIALOG(dlg)->vbox; - gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); - /* Print properties frame */ - GtkWidget *f = gtk_frame_new(_("Print properties")); - gtk_box_pack_start(GTK_BOX(vbox), f, FALSE, FALSE, 4); - GtkWidget *vb = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(f), vb); - gtk_container_set_border_width(GTK_CONTAINER(vb), 4); - /* Print type */ - bool const p2bm = mod->get_param_bool("bitmap"); - GtkWidget *rb = gtk_radio_button_new_with_label(NULL, _("Print using PDF operators")); - gtk_tooltips_set_tip((GtkTooltips *) tt, rb, - _("Use PDF vector operators. The resulting image is usually smaller " - "in file size and can be arbitrarily scaled, but " - "patterns will be lost."), NULL); - if (!p2bm) gtk_toggle_button_set_active((GtkToggleButton *) rb, TRUE); - gtk_box_pack_start(GTK_BOX(vb), rb, FALSE, FALSE, 0); - rb = gtk_radio_button_new_with_label(gtk_radio_button_get_group((GtkRadioButton *) rb), _("Print as bitmap")); - gtk_tooltips_set_tip((GtkTooltips *) tt, rb, - _("Print everything as bitmap. The resulting image is usually larger " - "in file size and cannot be arbitrarily scaled without quality loss, " - "but all objects will be rendered exactly as displayed."), NULL); - if (p2bm) gtk_toggle_button_set_active((GtkToggleButton *) rb, TRUE); - gtk_box_pack_start(GTK_BOX(vb), rb, FALSE, FALSE, 0); - /* Resolution */ - GtkWidget *hb = gtk_hbox_new(FALSE, 4); - gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); - GtkWidget *combo = gtk_combo_new(); - gtk_combo_set_value_in_list(GTK_COMBO(combo), FALSE, FALSE); - gtk_combo_set_use_arrows(GTK_COMBO(combo), TRUE); - gtk_combo_set_use_arrows_always(GTK_COMBO(combo), TRUE); - gtk_widget_set_size_request(combo, 64, -1); - gtk_tooltips_set_tip((GtkTooltips *) tt, GTK_COMBO(combo)->entry, - _("Preferred resolution (dots per inch) of bitmap"), NULL); - /* Setup strings */ - GList *sl = NULL; - for (unsigned i = 0; pdr[i] != NULL; i++) { - sl = g_list_prepend(sl, (gpointer) pdr[i]); - } - sl = g_list_reverse(sl); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), sl); - g_list_free(sl); - if (1) { - gchar const *val = mod->get_param_string("resolution"); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), val); - } - gtk_box_pack_end(GTK_BOX(hb), combo, FALSE, FALSE, 0); - GtkWidget *l = gtk_label_new(_("Resolution:")); - gtk_box_pack_end(GTK_BOX(hb), l, FALSE, FALSE, 0); - - /* Print destination frame */ - f = gtk_frame_new(_("Print destination")); - gtk_box_pack_start(GTK_BOX(vbox), f, FALSE, FALSE, 4); - vb = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(f), vb); - gtk_container_set_border_width(GTK_CONTAINER(vb), 4); - - l = gtk_label_new(_("Printer name (as given by lpstat -p);\n" - "leave empty to use the system default printer.\n" - "Use '> filename' to print to file.\n" - "Use '| prog arg...' to pipe to a program.")); - gtk_box_pack_start(GTK_BOX(vb), l, FALSE, FALSE, 0); - - GtkWidget *e = gtk_entry_new(); - if (1) { - gchar const *val = mod->get_param_string("destination"); - gtk_entry_set_text(GTK_ENTRY(e), ( val != NULL - ? val - : "" )); - } - gtk_box_pack_start(GTK_BOX(vb), e, FALSE, FALSE, 0); - - // pressing enter in the destination field is the same as clicking Print: - gtk_entry_set_activates_default(GTK_ENTRY(e), TRUE); - - gtk_widget_show_all(vbox); - - int const response = gtk_dialog_run(GTK_DIALOG(dlg)); - - g_object_unref((GObject *) tt); - - if (response == GTK_RESPONSE_OK) { - gchar const *fn; - char const *sstr; - - _bitmap = gtk_toggle_button_get_active((GtkToggleButton *) rb); - sstr = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); - _dpi = (unsigned int) MAX((int)(atof(sstr)), 1); - /* Arrgh, have to do something */ - fn = gtk_entry_get_text(GTK_ENTRY(e)); - /* skip leading whitespace, bug #1068483 */ - while (fn && *fn==' ') { fn++; } - /* g_print("Printing to %s\n", fn); */ - - mod->set_param_bool("bitmap", _bitmap); - mod->set_param_string("resolution", (gchar *)sstr); - mod->set_param_string("destination", (gchar *)fn); - ret = TRUE; - } - - gtk_widget_destroy(dlg); - - return ret; -} - -unsigned int -PrintCairoPDF::begin(Inkscape::Extension::Print *mod, SPDocument *doc) -{ - FILE *osf = NULL; - FILE *osp = NULL; - - _alpha_stack.clear(); - _alpha_stack.push_back(1.0); - - gsize bytesRead = 0; - gsize bytesWritten = 0; - GError *error = NULL; - gchar const *utf8_fn = mod->get_param_string("destination"); - gchar *local_fn = g_filename_from_utf8( utf8_fn, - -1, &bytesRead, &bytesWritten, &error); - gchar const *fn = local_fn; - - /* TODO: Replace the below fprintf's with something that does the right thing whether in - * gui or batch mode (e.g. --print=blah). Consider throwing an exception: currently one of - * the callers (sp_print_document_to_file, "ret = mod->begin(doc)") wrongly ignores the - * return code. - */ - if (fn != NULL) { - if (*fn == '|') { - fn += 1; - while (isspace(*fn)) fn += 1; -#ifndef WIN32 - osp = popen(fn, "w"); -#else - osp = _popen(fn, "w"); -#endif - if (!osp) { - fprintf(stderr, "inkscape: popen(%s): %s\n", - fn, strerror(errno)); - return 0; - } - _stream = osp; - } else if (*fn == '>') { - fn += 1; - while (isspace(*fn)) fn += 1; - Inkscape::IO::dump_fopen_call(fn, "K"); - osf = Inkscape::IO::fopen_utf8name(fn, "w+"); - if (!osf) { - fprintf(stderr, "inkscape: fopen(%s): %s\n", - fn, strerror(errno)); - return 0; - } - _stream = osf; - } else { - /* put cwd stuff in here */ - gchar *qn = ( *fn - ? g_strdup_printf("lpr -P %s", fn) /* FIXME: quote fn */ - : g_strdup("lpr") ); -#ifndef WIN32 - osp = popen(qn, "w"); -#else - osp = _popen(qn, "w"); -#endif - if (!osp) { - fprintf(stderr, "inkscape: popen(%s): %s\n", - qn, strerror(errno)); - return 0; - } - g_free(qn); - _stream = osp; - } - } - - g_free(local_fn); - - if (_stream) { - /* fixme: this is kinda icky */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_IGN); -#endif - } - - // test output stream? - - // width and height in pt - _width = sp_document_width(doc) * PT_PER_PX; - _height = sp_document_height(doc) * PT_PER_PX; - - NRRect d; - bool pageBoundingBox = mod->get_param_bool("pageBoundingBox"); - SPItem* doc_item = SP_ITEM(mod->base); - // printf("Page Bounding Box: %s\n", pageBoundingBox ? "TRUE" : "FALSE"); - Geom::Matrix t (Geom::identity()); - if (pageBoundingBox) { - d.x0 = d.y0 = 0; - d.x1 = _width; - d.y1 = _height; - } else { - // if not page, use our base, which is either root or the item we want to export - sp_item_invoke_bbox(doc_item, &d, sp_item_i2doc_affine (doc_item), TRUE); - // convert from px to pt - d.x0 *= PT_PER_PX; - d.x1 *= PT_PER_PX; - d.y0 *= PT_PER_PX; - d.y1 *= PT_PER_PX; - } - - // When rendering a standalone object, we must set cairo's transform to the accumulated - // ancestor transform of that item - e.g. it may be rotated or skewed by its parent group, and - // we must reproduce that in the export even though we start traversing the tree from the - // object itself, ignoring its ancestors - - // complete transform, including doc_item's own transform - t = sp_item_i2doc_affine (doc_item); - // subreact doc_item's transform (comes first) from it - t = Geom::Matrix(doc_item->transform).inverse() * t; - - // create cairo context - pdf_surface = cairo_pdf_surface_create_for_stream(Inkscape::Extension::Internal::_write_callback, _stream, d.x1-d.x0, d.y1-d.y0); - cr = cairo_create(pdf_surface); - - // move to the origin - cairo_translate (cr, -d.x0, -d.y0); - - // set cairo transform; we must scale the translation values to pt - _concat_transform (cr, t[0], t[1], t[2], t[3], t[4]*PT_PER_PX, t[5]*PT_PER_PX); - - if (!_bitmap) { - cairo_scale(cr, PT_PER_PX, PT_PER_PX); - - // from now on we can output px, but they will be treated as pt - // note that the we do not have to flip the y axis - // because Cairo's coordinate system is identical to Inkscape's - } - - return 1; -} - -unsigned int -PrintCairoPDF::finish(Inkscape::Extension::Print *mod) -{ - if (!_stream) return 0; - if (_bitmap) return 0; - - cairo_show_page(cr); - - cairo_destroy(cr); - cairo_surface_finish(pdf_surface); - cairo_status_t status = cairo_surface_status(pdf_surface); - cairo_surface_destroy(pdf_surface); - cr = NULL; - pdf_surface = NULL; - - /* Flush stream to be sure. */ - (void) fflush(_stream); - - /* fixme: should really use pclose for popen'd streams */ - fclose(_stream); - _stream = 0; - - if (status == CAIRO_STATUS_SUCCESS) - return true; - else - return false; -} - -unsigned int -PrintCairoPDF::bind(Inkscape::Extension::Print *mod, Geom::Matrix const *transform, float opacity) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - if (opacity < 1.0) { - cairo_push_group(cr); - } else { - cairo_save(cr); - } - _concat_transform(cr, (*transform)[0], (*transform)[1], (*transform)[2], (*transform)[3], (*transform)[4], (*transform)[5]); - // printf("bind: (%f) %f %f %f %f %f %f\n", opacity, transform->c[0], transform->c[1], transform->c[2], transform->c[3], transform->c[4], transform->c[5]); - // remember these to be able to undo them when outputting text - _last_tx = (*transform)[4]; - _last_ty = (*transform)[5]; - - _alpha_stack.push_back(opacity); - - return 1; -} - -unsigned int -PrintCairoPDF::release(Inkscape::Extension::Print *mod) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - float opacity = _alpha_stack.back(); - - if (opacity < 1.0) { - cairo_pop_group_to_source(cr); - cairo_paint_with_alpha(cr, opacity); - } else { - cairo_restore(cr); - } -// g_printf("release\n"); - _alpha_stack.pop_back(); - g_assert(_alpha_stack.size() > 0); - - return 1; -} - -unsigned int -PrintCairoPDF::comment(Inkscape::Extension::Print *mod, char const *comment) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - return 1; -} - -cairo_pattern_t* -PrintCairoPDF::create_pattern_for_paint(SPPaintServer const *const paintserver, NRRect const *pbox, float alpha) -{ - cairo_pattern_t *pattern = NULL; - bool apply_bbox2user = false; - - if (SP_IS_LINEARGRADIENT (paintserver)) { - - SPLinearGradient *lg=SP_LINEARGRADIENT(paintserver); - - sp_gradient_ensure_vector(SP_GRADIENT(lg)); // when exporting from commandline, vector is not built - - Geom::Point p1 (lg->x1.computed, lg->y1.computed); - Geom::Point p2 (lg->x2.computed, lg->y2.computed); - if (pbox && SP_GRADIENT(lg)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - // convert to userspace - Geom::Matrix bbox2user(pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); - p1 *= bbox2user; - p2 *= bbox2user; - } - - // create linear gradient pattern - pattern = cairo_pattern_create_linear(p1[Geom::X], p1[Geom::Y], p2[Geom::X], p2[Geom::Y]); - - // add stops - for (gint i = 0; unsigned(i) < lg->vector.stops.size(); i++) { - float rgb[3]; - sp_color_get_rgb_floatv(&lg->vector.stops[i].color, rgb); - cairo_pattern_add_color_stop_rgba(pattern, lg->vector.stops[i].offset, rgb[0], rgb[1], rgb[2], lg->vector.stops[i].opacity * alpha); - } - } else if (SP_IS_RADIALGRADIENT (paintserver)) { - - SPRadialGradient *rg=SP_RADIALGRADIENT(paintserver); - - sp_gradient_ensure_vector(SP_GRADIENT(rg)); // when exporting from commandline, vector is not built - - Geom::Point c (rg->cx.computed, rg->cy.computed); - Geom::Point f (rg->fx.computed, rg->fy.computed); - double r = rg->r.computed; - - Geom::Coord const df = hypot(f[Geom::X] - c[Geom::X], f[Geom::Y] - c[Geom::Y]); - if (df >= r) { - f[Geom::X] = c[Geom::X] + (f[Geom::X] - c[Geom::X] ) * r / (float) df; - f[Geom::Y] = c[Geom::Y] + (f[Geom::Y] - c[Geom::Y] ) * r / (float) df; - } - - if (pbox && SP_GRADIENT(rg)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) - apply_bbox2user = true; - - // create radial gradient pattern - pattern = cairo_pattern_create_radial(f[Geom::X], f[Geom::Y], 0, c[Geom::X], c[Geom::Y], r); - - // add stops - for (gint i = 0; unsigned(i) < rg->vector.stops.size(); i++) { - float rgb[3]; - sp_color_get_rgb_floatv(&rg->vector.stops[i].color, rgb); - cairo_pattern_add_color_stop_rgba(pattern, rg->vector.stops[i].offset, rgb[0], rgb[1], rgb[2], rg->vector.stops[i].opacity * alpha); - } - } - - if (pattern) { - SPGradient *g = SP_GRADIENT(paintserver); - - // set extend type - SPGradientSpread spread = sp_gradient_get_spread(g); - switch (spread) { - case SP_GRADIENT_SPREAD_REPEAT: - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); - break; - case SP_GRADIENT_SPREAD_REFLECT: - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT); - break; - case SP_GRADIENT_SPREAD_PAD: - default: - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); - break; - } - - cairo_matrix_t pattern_matrix; - if (g->gradientTransform_set) { - // apply gradient transformation - cairo_matrix_init(&pattern_matrix, - g->gradientTransform[0], g->gradientTransform[1], - g->gradientTransform[2], g->gradientTransform[3], - g->gradientTransform[4], g->gradientTransform[5]); - } else { - cairo_matrix_init_identity (&pattern_matrix); - } - - if (apply_bbox2user) { - // convert to userspace - cairo_matrix_t bbox2user; - cairo_matrix_init (&bbox2user, pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); - cairo_matrix_multiply (&pattern_matrix, &bbox2user, &pattern_matrix); - } - cairo_matrix_invert(&pattern_matrix); // because Cairo expects a userspace->patternspace matrix - cairo_pattern_set_matrix(pattern, &pattern_matrix); - } - - return pattern; -} - -void -PrintCairoPDF::print_fill_style(cairo_t *cr, SPStyle const *const style, NRRect const *pbox) -{ - g_return_if_fail( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ); - - if (style->fill.isColor()) { - float rgb[3]; - sp_color_get_rgb_floatv(&style->fill.value.color, rgb); - - float alpha = SP_SCALE24_TO_FLOAT(style->fill_opacity.value); - - cairo_set_source_rgba(cr, rgb[0], rgb[1], rgb[2], alpha); - } else { - g_assert( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ); - - cairo_pattern_t *pattern = create_pattern_for_paint(SP_STYLE_FILL_SERVER(style), pbox, 1.0); - - if (pattern) { - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - } - } -} - -unsigned int -PrintCairoPDF::fill(Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *const style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - if ( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) { - - float alpha = SP_SCALE24_TO_FLOAT(style->fill_opacity.value); - - cairo_save(cr); - - print_fill_style(cr, style, pbox); - - cairo_new_path(cr); - feed_pathvector_to_cairo(cr, pathv); - - if (style->fill_rule.computed == SP_WIND_RULE_EVENODD) { - cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); - } else { - cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING); - } - if (alpha != 1.0 && - !style->fill.isColor()) { - - cairo_clip (cr); - cairo_paint_with_alpha (cr, alpha); - } else { - cairo_fill(cr); - } - - cairo_restore(cr); - } - - return 0; -} - -void -PrintCairoPDF::print_stroke_style(cairo_t *cr, SPStyle const *style, NRRect const *pbox) -{ - float alpha = SP_SCALE24_TO_FLOAT(style->stroke_opacity.value); - - if ( style->stroke.isColor() ) { - float rgb[3]; - sp_color_get_rgb_floatv(&style->stroke.value.color, rgb); - - cairo_set_source_rgba(cr, rgb[0], rgb[1], rgb[2], alpha); - } else if ( style->stroke.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) ) { - - cairo_pattern_t *pattern = create_pattern_for_paint(SP_STYLE_STROKE_SERVER(style), pbox, alpha); - - if (pattern) { - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - } - } - - if (style->stroke_dash.n_dash && - style->stroke_dash.dash ) - { - cairo_set_dash(cr, style->stroke_dash.dash, style->stroke_dash.n_dash, style->stroke_dash.offset); - } else { - cairo_set_dash(cr, NULL, 0, 0.0); // disable dashing - } - - cairo_set_line_width(cr, style->stroke_width.computed); - - // set line join type - cairo_line_join_t join = CAIRO_LINE_JOIN_MITER; - switch (style->stroke_linejoin.computed) { - case SP_STROKE_LINEJOIN_MITER: - join = CAIRO_LINE_JOIN_MITER; - break; - case SP_STROKE_LINEJOIN_ROUND: - join = CAIRO_LINE_JOIN_ROUND; - break; - case SP_STROKE_LINEJOIN_BEVEL: - join = CAIRO_LINE_JOIN_BEVEL; - break; - } - cairo_set_line_join(cr, join); - - // set line cap type - cairo_line_cap_t cap = CAIRO_LINE_CAP_BUTT; - switch (style->stroke_linecap.computed) { - case SP_STROKE_LINECAP_BUTT: - cap = CAIRO_LINE_CAP_BUTT; - break; - case SP_STROKE_LINECAP_ROUND: - cap = CAIRO_LINE_CAP_ROUND; - break; - case SP_STROKE_LINECAP_SQUARE: - cap = CAIRO_LINE_CAP_SQUARE; - break; - } - cairo_set_line_cap(cr, cap); - cairo_set_miter_limit(cr, MAX(1, style->stroke_miterlimit.value)); -} - -unsigned int -PrintCairoPDF::stroke(Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - if ( style->stroke.isColor() || - ( style->stroke.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) ) ) { - - cairo_save(cr); - - cairo_new_path(cr); - print_stroke_style(cr, style, pbox); - - feed_pathvector_to_cairo(cr, pathv); - cairo_stroke(cr); - - cairo_restore(cr); - } - - return 0; -} - -unsigned int -PrintCairoPDF::image(Inkscape::Extension::Print *mod, guchar *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *transform, SPStyle const *style) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - guchar* px_rgba = (guchar*)g_malloc(4 * w * h); - if (!px_rgba) return 0; - - float alpha = _alpha_stack.back(); - - // make a copy of the original pixbuf with premultiplied alpha - // if we pass the original pixbuf it will get messed up - for (unsigned i = 0; i < h; i++) { - for (unsigned j = 0; j < w; j++) { - guchar const *src = px + i * rs + j * 4; - guint32 *dst = (guint32 *)(px_rgba + i * rs + j * 4); - guchar r, g, b, alpha_dst; - - // calculate opacity-modified alpha - alpha_dst = src[3]; - if (alpha != 1.0) - alpha_dst = (guchar)ceil((float)alpha_dst * alpha); - - // premul alpha (needed because this will be undone by cairo-pdf) - r = src[0]*alpha_dst/255; - g = src[1]*alpha_dst/255; - b = src[2]*alpha_dst/255; - - *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b)); - } - } - - cairo_surface_t *image_surface = cairo_image_surface_create_for_data(px_rgba, CAIRO_FORMAT_ARGB32, w, h, w * 4); - if (cairo_surface_status(image_surface)) { - g_printf("Error: %s\n", cairo_status_to_string(cairo_surface_status(image_surface))); - return 0; - } - - cairo_save(cr); - - // scaling by width & height is not needed because it will be done by cairo-pdf - // we have to translate down by height also in order to eliminate the last translation done by sp_image_print - cairo_matrix_t matrix; - cairo_matrix_init(&matrix, - (*transform)[0]/w, (*transform)[1], - (*transform)[2], -(*transform)[3]/h, - (*transform)[4], (*transform)[5] + (*transform)[3]); - cairo_transform(cr, &matrix); - - cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image_surface); - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_NONE); - - cairo_set_source(cr, pattern); - cairo_pattern_destroy(pattern); - - // set clip region so that the pattern will not be repeated (bug in Cairo prior 1.2.1) - cairo_new_path(cr); - cairo_rectangle(cr, 0, 0, w, h); - cairo_clip(cr); - - cairo_paint(cr); - - cairo_restore(cr); - - cairo_surface_destroy(image_surface); - g_free(px_rgba); - - return 0; -} - -#define GLYPH_ARRAY_SIZE 64 - -#ifndef RENDER_WITH_PANGO_CAIRO - -Geom::Point -PrintCairoPDF::draw_glyphs(cairo_t *cr, Geom::Point p, PangoFont *font, PangoGlyphString *glyph_string, - bool vertical, bool stroke) -{ - cairo_glyph_t glyph_array[GLYPH_ARRAY_SIZE]; - cairo_glyph_t *glyphs = glyph_array; - if (glyph_string->num_glyphs > GLYPH_ARRAY_SIZE) - glyphs = (cairo_glyph_t*)g_malloc(sizeof(cairo_glyph_t) * glyph_string->num_glyphs); - - PangoGlyphUnit x_offset = 0, y_offset = 0; - PangoGlyphInfo *info; - int num_invalid_glyphs = 0; - for (gint i = 0; i < glyph_string->num_glyphs; i++) { - info = &glyph_string->glyphs[i]; - // skip glyphs which are PANGO_GLYPH_EMPTY (0x0FFFFFFF) or have - // the PANGO_GLYPH_UNKNOWN_FLAG (0x10000000) set - if (info->glyph == 0x0FFFFFFF || info->glyph & 0x10000000) { - num_invalid_glyphs++; - continue; - } - - glyphs[i - num_invalid_glyphs].index = info->glyph; - glyphs[i - num_invalid_glyphs].x = p[Geom::X] + (x_offset + info->geometry.x_offset)/PANGO_SCALE; - glyphs[i - num_invalid_glyphs].y = p[Geom::Y] + (y_offset + info->geometry.y_offset)/PANGO_SCALE; - - if (vertical) { - cairo_text_extents_t extents; - cairo_glyph_extents(cr, &glyphs[i - num_invalid_glyphs], 1, &extents); - y_offset += (PangoGlyphUnit)(extents.y_advance * PANGO_SCALE); - } - else - x_offset += info->geometry.width; - } - - if (stroke) - cairo_glyph_path(cr, glyphs, glyph_string->num_glyphs - num_invalid_glyphs); - else - cairo_show_glyphs(cr, glyphs, glyph_string->num_glyphs - num_invalid_glyphs); - - if (glyph_string->num_glyphs > GLYPH_ARRAY_SIZE) - g_free(glyphs); - - return Geom::Point(x_offset, y_offset); -} -#endif - - - -unsigned int -PrintCairoPDF::text(Inkscape::Extension::Print *mod, char const *text, Geom::Point p, - SPStyle const *const style) -{ - bool dirty_pattern = false; - - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - cairo_save(cr); - - // this needs to be there to encounter Cairo's userspace locking semantics for set_source - // otherwise gradients won't be shown correctly - // printf("\n _last_tx:%f _last_ty:%f", _last_tx, _last_ty); - cairo_translate(cr, -_last_tx, -_last_ty); - - // create pango layout and context if needed - if (_layout == NULL) { -#ifdef RENDER_WITH_PANGO_CAIRO - //_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(pango_cairo_font_map_get_default())); - _layout = pango_cairo_create_layout(cr); -#else - _layout = pango_layout_new((font_factory::Default())->fontContext); -#endif - } - - // create font instance from style and use it - font_instance *tf = font_factory::Default()->FaceFromStyle(style); - if (tf == NULL) { // do something - g_printf("Warning: trouble getting font_instance\n"); - tf = (font_factory::Default())->Face("sans", font_style_to_pos(*style)); - } - PangoFontDescription *adjusted = pango_font_description_copy(tf->descr); - - pango_font_description_set_absolute_size(adjusted, (gint)(style->font_size.computed * PANGO_SCALE)); - pango_layout_set_font_description(_layout, adjusted); - pango_layout_set_text(_layout, text, -1); - - pango_font_description_free(adjusted); - tf->Unref(); - -#ifdef RENDER_WITH_PANGO_CAIRO - pango_cairo_update_layout(cr, _layout); -#else - pango_layout_context_changed(_layout); // is this needed? -#endif - - PangoLayoutLine *line = pango_layout_get_line(_layout, 0); - if (line == NULL) - return 0; - -#ifndef RENDER_WITH_PANGO_CAIRO - // apply the selected font - double size; - PangoLayoutRun *first_run = (PangoLayoutRun *)line->runs->data; - PangoFcFont *fc_font = PANGO_FC_FONT(first_run->item->analysis.font); - FcPattern *fc_pattern = fc_font->font_pattern; - - if ( style->writing_mode.set && - (style->writing_mode.computed == SP_CSS_WRITING_MODE_TB_RL || - style->writing_mode.computed == SP_CSS_WRITING_MODE_TB_LR) ) - { - FcPatternDel(fc_pattern, FC_VERTICAL_LAYOUT); - FcPatternAddBool(fc_pattern, FC_VERTICAL_LAYOUT, FcTrue); - dirty_pattern = true; - } - - cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(fc_pattern); - cairo_set_font_face(cr, font_face); - - if (FcPatternGetDouble(fc_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch) - size = 12.0; - - // adjust size and horizontal flip - cairo_matrix_t matrix; - cairo_get_font_matrix(cr, &matrix); - matrix.xx = size; - matrix.yy = -matrix.xx; - cairo_set_font_matrix(cr, &matrix); -#endif - - if ( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) - { - // set fill style - print_fill_style(cr, style, NULL); - -#ifndef RENDER_WITH_PANGO_CAIRO - Geom::Point cursor(_last_tx, _last_ty); - for (GSList *tmpList = line->runs; tmpList && tmpList->data; tmpList = tmpList->next) { - PangoLayoutRun *run = (PangoLayoutRun *)tmpList->data; - cursor += draw_glyphs(cr, cursor, run->item->analysis.font, run->glyphs, dirty_pattern, false) / PANGO_SCALE; - } -#else - cairo_new_path(cr); - // as pango has inverted origin we simulate the moveto and apply the vertical flip - //cairo_move_to(cr, _last_tx, _last_ty); - cairo_translate(cr, _last_tx, _last_ty); - cairo_scale(cr, 1, -1); - cairo_move_to(cr, 0, 0); - pango_cairo_show_layout_line(cr, line); - cairo_scale(cr, 1, -1); - cairo_translate(cr, -_last_tx, -_last_ty); - -#endif - } - - if (style->stroke.isColor() - || ( style->stroke.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) ) ) - { - // set stroke style - print_stroke_style(cr, style, NULL); - - // paint stroke -#ifndef RENDER_WITH_PANGO_CAIRO - Geom::Point cursor(_last_tx, _last_ty); - for (GSList *tmpList = line->runs; tmpList && tmpList->data; tmpList = tmpList->next) { - PangoLayoutRun *run = (PangoLayoutRun *)tmpList->data; - cursor += draw_glyphs(cr, cursor, run->item->analysis.font, run->glyphs, dirty_pattern, true) / PANGO_SCALE; - } -#else - cairo_new_path(cr); - // as pango has inverted origin we simulate the moveto and apply the vertical flip - //cairo_move_to(cr, _last_tx, _last_ty); - cairo_translate(cr, _last_tx, _last_ty); - cairo_scale(cr, 1, -1); - cairo_move_to(cr, 0, 0); - pango_cairo_layout_line_path(cr, line); - cairo_scale(cr, 1, -1); - cairo_translate(cr, -_last_tx, -_last_ty); -#endif - cairo_stroke(cr); - } - - - cairo_restore(cr); - -#ifndef RENDER_WITH_PANGO_CAIRO - cairo_font_face_destroy(font_face); - - if (dirty_pattern) { - FcPatternDel(fc_pattern, FC_VERTICAL_LAYOUT); - FcPatternAddBool(fc_pattern, FC_VERTICAL_LAYOUT, FcFalse); - } -#endif - - return 0; -} - -/* Helper functions */ - -static void -_concat_transform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0) -{ - cairo_matrix_t matrix; - - cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0); - cairo_transform(cr, &matrix); -} - -static cairo_status_t -_write_callback(void *closure, const unsigned char *data, unsigned int length) -{ - size_t written; - FILE *file = (FILE*)closure; - - written = fwrite (data, 1, length, file); - - if (written == length) - return CAIRO_STATUS_SUCCESS; - else - return CAIRO_STATUS_WRITE_ERROR; -} - -bool -PrintCairoPDF::textToPath(Inkscape::Extension::Print * ext) -{ - return ext->get_param_bool("textToPath"); -} - -#include "clear-n_.h" - -void -PrintCairoPDF::init(void) -{ - /* PDF out */ - (void) Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("PDF Print") "</name>\n" - "<id>" SP_MODULE_KEY_PRINT_CAIRO_PDF "</id>\n" - "<param name=\"bitmap\" type=\"boolean\">false</param>\n" - "<param name=\"resolution\" type=\"string\">72</param>\n" - "<param name=\"destination\" type=\"string\">| lp</param>\n" - "<param name=\"pageBoundingBox\" type=\"boolean\">true</param>\n" - "<param name=\"textToPath\" type=\"boolean\">true</param>\n" - "<param name=\"exportDrawing\" type=\"boolean\">false</param>\n" - "<param name=\"exportCanvas\" type=\"boolean\">false</param>\n" - "<param name=\"exportId\" type=\"string\"></param>\n" - "<print/>\n" - "</inkscape-extension>", new PrintCairoPDF()); -} - - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - -/* End of GNU GPL code */ - -#endif /* HAVE_CAIRO_PDF */ - - -/* - 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/extension/internal/pdf-cairo.h b/src/extension/internal/pdf-cairo.h deleted file mode 100644 index 2b81fa30e..000000000 --- a/src/extension/internal/pdf-cairo.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef EXTENSION_INTERNAL_PDF_CAIRO_H_SEEN -#define EXTENSION_INTERNAL_PDF_CAIRO_H_SEEN - -/** \file - * Declaration of PrintCairoPDF, the internal module used to do PDF printing with Cairo. - */ -/* - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * Ted Gould <ted@gould.cx> - * - * Lauris' original code is in the public domain. - * Ted's changes are licensed under the GNU GPL. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_CAIRO_PDF - -#include "extension/extension.h" -#include "extension/implementation/implementation.h" -#include <set> -#include <string> - -#include "libnrtype/font-instance.h" - -#include "svg/stringstream.h" -#include "sp-gradient.h" - -#include <cairo.h> - -namespace Inkscape { -namespace Extension { -namespace Internal { - -class PrintCairoPDF : public Inkscape::Extension::Implementation::Implementation { - float _width; - float _height; - FILE *_stream; - cairo_t *cr; - cairo_surface_t *pdf_surface; - PangoLayout *_layout; -// PangoContext *_context; - std::vector<float> _alpha_stack; - double _last_tx, _last_ty; - - unsigned short _dpi; - bool _bitmap; - - cairo_pattern_t *create_pattern_for_paint(SPPaintServer const *const paintserver, NRRect const *pbox, float alpha); - - void print_fill_style(cairo_t *cr, SPStyle const *const style, NRRect const *pbox); - void print_stroke_style(cairo_t *cr, SPStyle const *style, NRRect const *pbox); - -#ifndef RENDER_WITH_PANGO_CAIRO - Geom::Point draw_glyphs(cairo_t *cr, Geom::Point p, PangoFont *font, PangoGlyphString *glyph_string, - bool vertical, bool stroke); -#endif - -public: - PrintCairoPDF(void); - virtual ~PrintCairoPDF(void); - - /* Print functions */ - virtual unsigned int setup(Inkscape::Extension::Print *module); - /* - virtual unsigned int set_preview(Inkscape::Extension::Print *module); - */ - - virtual unsigned int begin(Inkscape::Extension::Print *module, SPDocument *doc); - virtual unsigned int finish(Inkscape::Extension::Print *module); - - /* Rendering methods */ - virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Matrix const *transform, float opacity); - virtual unsigned int release(Inkscape::Extension::Print *module); - virtual unsigned int comment(Inkscape::Extension::Print *module, char const *comment); - virtual unsigned int fill(Inkscape::Extension::Print *module, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); - virtual unsigned int stroke(Inkscape::Extension::Print *module, Geom::PathVector const &pathv, Geom::Matrix const *transform, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); - virtual unsigned int image(Inkscape::Extension::Print *module, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *transform, SPStyle const *style); - virtual unsigned int text(Inkscape::Extension::Print *module, char const *text, - Geom::Point p, SPStyle const *style); - - bool textToPath(Inkscape::Extension::Print *ext); - static void init(void); -}; - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* HAVE_CAIRO_PDF */ - -#endif /* !EXTENSION_INTERNAL_PDF_CAIRO_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 : diff --git a/src/extension/internal/ps-out.cpp b/src/extension/internal/ps-out.cpp deleted file mode 100644 index ba9338198..000000000 --- a/src/extension/internal/ps-out.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * A quick hack to use the print output to write out a file. This - * then makes 'save as...' Postscript. - * - * Authors: - * Ted Gould <ted@gould.cx> - * - * Copyright (C) 2004 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "ps-out.h" -#include <print.h> -#include "extension/system.h" -#include "extension/db.h" -#include "extension/output.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -bool -PsOutput::check( Inkscape::Extension::Extension * /*module*/ ) -{ - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_PS)) - return FALSE; - - return TRUE; -} - -/** - \brief This function calls the print system with the filename - \param mod unused - \param doc Document to be saved - \param uri Filename to save to (probably will end in .ps) - - The most interesting thing that this function does is just attach - an '>' on the front of the filename. This is the syntax used to - tell the printing system to save to file. -*/ -void -PsOutput::save (Inkscape::Extension::Output *mod, SPDocument *doc, const gchar *uri) -{ - Inkscape::Extension::Extension * ext; - - ext = Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_PS); - if (ext == NULL) - return; - - bool old_textToPath = ext->get_param_bool("textToPath"); - bool new_val = mod->get_param_bool("textToPath"); - ext->set_param_bool("textToPath", new_val); - - gchar * final_name; - final_name = g_strdup_printf("> %s", uri); - sp_print_document_to_file(doc, final_name); - g_free(final_name); - - ext->set_param_bool("textToPath", old_textToPath); - - return; -} - -#include "clear-n_.h" - -/** - \brief A function allocate a copy of this function. - - This is the definition of postscript out. This function just - calls the extension system with the memory allocated XML that - describes the data. -*/ -void -PsOutput::init (void) -{ - Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Postscript Output") "</name>\n" - "<id>org.inkscape.output.ps</id>\n" - "<param name=\"textToPath\" gui-text=\"" N_("Convert texts to paths") "\" type=\"boolean\">true</param>\n" - "<param name=\"fontEmbedded\" gui-text=\"" N_("Embed fonts (Type 1 only)") "\" type=\"boolean\">false</param>\n" - "<output>\n" - "<extension>.ps</extension>\n" - "<mimetype>image/x-postscript</mimetype>\n" - "<filetypename>" N_("PostScript (old exporter via print) (*.ps)") "</filetypename>\n" - "<filetypetooltip>" N_("PostScript File") "</filetypetooltip>\n" - "</output>\n" - "</inkscape-extension>", new PsOutput()); - - return; -} - -} } } /* namespace Inkscape, Extension, Implementation */ diff --git a/src/extension/internal/ps-out.h b/src/extension/internal/ps-out.h deleted file mode 100644 index 592f3d70e..000000000 --- a/src/extension/internal/ps-out.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * A quick hack to use the print output to write out a file. This - * then makes 'save as...' Postscript. - * - * Authors: - * Ted Gould <ted@gould.cx> - * - * Copyright (C) 2004 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef EXTENSION_INTERNAL_PS_OUT_H -#define EXTENSION_INTERNAL_PS_OUT_H - -#include "extension/implementation/implementation.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -class PsOutput : Inkscape::Extension::Implementation::Implementation { - -public: - bool check(Inkscape::Extension::Extension *module); - void save(Inkscape::Extension::Output *mod, - SPDocument *doc, - gchar const *uri); - static void init(); -}; - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* !EXTENSION_INTERNAL_PS_OUT_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:encoding=utf-8:textwidth=99 : diff --git a/src/extension/internal/ps.cpp b/src/extension/internal/ps.cpp deleted file mode 100644 index f8b3d999e..000000000 --- a/src/extension/internal/ps.cpp +++ /dev/null @@ -1,1797 +0,0 @@ -#define __SP_PS_C__ - -/** \file - * PostScript printing. - */ -/* - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * bulia byak <buliabyak@users.sf.net> - * - * Basic printing code, EXCEPT image and - * ascii85 filter is in public domain - * - * Image printing and Ascii85 filter: - * - * Copyright (C) 2006 Johan Engelen - * Copyright (C) 1997-98 Peter Kirchgessner - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * George White <aa056@chebucto.ns.ca> - * Austin Donnelly <austin@gimp.org> - * - * Licensed under GNU GPL - */ - -/* Plain Print */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <signal.h> -#include <errno.h> - -#include <libnr/nr-matrix-fns.h> - -#include <glib/gmem.h> -#include <glib/gstrfuncs.h> -#include <gtk/gtkstock.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkframe.h> -#include <gtk/gtkradiobutton.h> -#include <gtk/gtkcombo.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkentry.h> -#include <gtk/gtktooltips.h> - -#include <glibmm/i18n.h> -#include "display/nr-arena-item.h" -#include "display/canvas-bpath.h" -#include "sp-item.h" -#include "style.h" -#include "sp-linear-gradient.h" -#include "sp-radial-gradient.h" - -#include "libnrtype/font-instance.h" -#include "libnrtype/font-style-to-pos.h" - -#include <unit-constants.h> - -#include "ps.h" -#include "extension/system.h" -#include "extension/print.h" - -#include "io/sys.h" - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_XFREE86_H -#include <pango/pangoft2.h> -#include <string> -#include <iostream> -#include <fstream> -#include <cstring> -#include <cstdio> -#include <cstdlib> -#include <cmath> - -#include <2geom/sbasis-to-bezier.h> -#include <2geom/bezier-curve.h> -#include <2geom/hvlinesegment.h> -#include "helper/geom-curves.h" - -/* -using std::atof; -using std::ceil; -using std::fclose; -using std::ferror; -using std::fflush; -using std::fgetc; -using std::fprintf; --> this line will result 'std::libintl_fprintf' has not been declared -using std::fputc; -using std::fseek; -using std::ifstream; -using std::ios; -using std::memset; -using std::strchr; -using std::strcmp; -using std::strerror; -using std::tmpfile; -*/ -using namespace std; - -namespace Inkscape { -namespace Extension { -namespace Internal { - -PrintPS::PrintPS() : - _stream(NULL), - _dpi(72), - _bitmap(false) -{ - //map font types - _fontTypesMap["Type 1"] = FONT_TYPE1; - _fontTypesMap["TrueType"] = FONT_TRUETYPE; - //TODO: support other font types (cf. embed_font()) -} - -PrintPS::~PrintPS(void) -{ - /* fixme: should really use pclose for popen'd streams */ - if (_stream) fclose(_stream); - if(_begin_stream) fclose(_begin_stream); - if(_fonts) g_tree_destroy(_fonts); - - /* restore default signal handling for SIGPIPE */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_DFL); -#endif - - return; -} - -unsigned int -PrintPS::setup(Inkscape::Extension::Print * mod) -{ - static gchar const *const pdr[] = {"72", "75", "100", "144", "150", "200", "300", "360", "600", "1200", "2400", NULL}; - -#ifdef TED - Inkscape::XML::Node *repr = ((SPModule *) mod)->repr; -#endif - - unsigned int ret = FALSE; - gchar const *destination = mod->get_param_string("destination"); - - /* Create dialog */ - GtkTooltips *tt = gtk_tooltips_new(); - g_object_ref((GObject *) tt); - gtk_object_sink((GtkObject *) tt); - - GtkWidget *dlg = gtk_dialog_new_with_buttons( - destination ? _("Print Configuration") : _("Print Destination"), -// SP_DT_WIDGET(SP_ACTIVE_DESKTOP)->window, - NULL, - (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - destination ? GTK_STOCK_GO_FORWARD : GTK_STOCK_PRINT, - GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_default_response(GTK_DIALOG(dlg), GTK_RESPONSE_OK); - - GtkWidget *vbox = GTK_DIALOG(dlg)->vbox; - gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); - /* Print properties frame */ - GtkWidget *f = gtk_frame_new(_("Print properties")); - gtk_box_pack_start(GTK_BOX(vbox), f, FALSE, FALSE, 4); - GtkWidget *vb = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(f), vb); - gtk_container_set_border_width(GTK_CONTAINER(vb), 4); - /* Print type */ - bool const p2bm = mod->get_param_bool("bitmap"); - GtkWidget *rb = gtk_radio_button_new_with_label(NULL, _("Print using PostScript operators")); - gtk_tooltips_set_tip((GtkTooltips *) tt, rb, - _("Use PostScript vector operators. The resulting image is usually smaller " - "in file size and can be arbitrarily scaled, but alpha transparency " - "and patterns will be lost."), NULL); - if (!p2bm) gtk_toggle_button_set_active((GtkToggleButton *) rb, TRUE); - gtk_box_pack_start(GTK_BOX(vb), rb, FALSE, FALSE, 0); - rb = gtk_radio_button_new_with_label(gtk_radio_button_get_group((GtkRadioButton *) rb), _("Print as bitmap")); - gtk_tooltips_set_tip((GtkTooltips *) tt, rb, - _("Print everything as bitmap. The resulting image is usually larger " - "in file size and cannot be arbitrarily scaled without quality loss, " - "but all objects will be rendered exactly as displayed."), NULL); - if (p2bm) gtk_toggle_button_set_active((GtkToggleButton *) rb, TRUE); - gtk_box_pack_start(GTK_BOX(vb), rb, FALSE, FALSE, 0); - /* Resolution */ - GtkWidget *hb = gtk_hbox_new(FALSE, 4); - gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); - GtkWidget *combo = gtk_combo_new(); - gtk_combo_set_value_in_list(GTK_COMBO(combo), FALSE, FALSE); - gtk_combo_set_use_arrows(GTK_COMBO(combo), TRUE); - gtk_combo_set_use_arrows_always(GTK_COMBO(combo), TRUE); - gtk_widget_set_size_request(combo, 64, -1); - gtk_tooltips_set_tip((GtkTooltips *) tt, GTK_COMBO(combo)->entry, - _("Preferred resolution (dots per inch) of bitmap"), NULL); - /* Setup strings */ - GList *sl = NULL; - for (unsigned i = 0; pdr[i] != NULL; i++) { - sl = g_list_prepend(sl, (gpointer) pdr[i]); - } - sl = g_list_reverse(sl); - gtk_combo_set_popdown_strings(GTK_COMBO(combo), sl); - g_list_free(sl); - if (1) { - gchar const *val = mod->get_param_string("resolution"); - gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), val); - } - gtk_box_pack_end(GTK_BOX(hb), combo, FALSE, FALSE, 0); - GtkWidget *l = gtk_label_new(_("Resolution:")); - gtk_box_pack_end(GTK_BOX(hb), l, FALSE, FALSE, 0); - - GtkWidget *e = NULL; - /* if the destination isn't already set, we must prompt for it */ - if (!destination) { - /* Print destination frame */ - f = gtk_frame_new(_("Print destination")); - gtk_box_pack_start(GTK_BOX(vbox), f, FALSE, FALSE, 4); - vb = gtk_vbox_new(FALSE, 4); - gtk_container_add(GTK_CONTAINER(f), vb); - gtk_container_set_border_width(GTK_CONTAINER(vb), 4); - - l = gtk_label_new(_("Printer name (as given by lpstat -p);\n" - "leave empty to use the system default printer.\n" - "Use '> filename' to print to file.\n" - "Use '| prog arg...' to pipe to a program.")); - gtk_box_pack_start(GTK_BOX(vb), l, FALSE, FALSE, 0); - - e = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(e), ( destination != NULL - ? destination - : "" )); - gtk_box_pack_start(GTK_BOX(vb), e, FALSE, FALSE, 0); - - // pressing enter in the destination field is the same as clicking Print: - gtk_entry_set_activates_default(GTK_ENTRY(e), TRUE); - } - - gtk_widget_show_all(vbox); - - int const response = gtk_dialog_run(GTK_DIALOG(dlg)); - - g_object_unref((GObject *) tt); - - if (response == GTK_RESPONSE_OK) { - gchar const *fn; - char const *sstr; - - _bitmap = gtk_toggle_button_get_active((GtkToggleButton *) rb); - sstr = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); - _dpi = (unsigned int) MAX((int)(atof(sstr)), 1); - - /* if the destination was prompted for, record the new value */ - if (e) { - /* Arrgh, have to do something */ - fn = gtk_entry_get_text(GTK_ENTRY(e)); - /* skip leading whitespace, bug #1068483 */ - while (fn && *fn==' ') { fn++; } - /* g_print("Printing to %s\n", fn); */ - - mod->set_param_string("destination", (gchar *)fn); - } - mod->set_param_bool("bitmap", _bitmap); - mod->set_param_string("resolution", (gchar *)sstr); - ret = TRUE; - } - - gtk_widget_destroy(dlg); - - return ret; -} - -unsigned int -PrintPS::begin(Inkscape::Extension::Print *mod, SPDocument *doc) -{ - gboolean epsexport = false; - - - _latin1_encoded_fonts.clear(); - _newlatin1font_proc_defined = false; - - FILE *osf = NULL; - FILE *osp = NULL; - FILE *osf_tmp = NULL; - - gsize bytesRead = 0; - gsize bytesWritten = 0; - GError *error = NULL; - //check whether fonts have to be embedded in the (EPS only) output - bool font_embedded = mod->fontEmbedded(); - gchar const *utf8_fn = mod->get_param_string("destination"); - gchar *local_fn = g_filename_from_utf8( utf8_fn, - -1, &bytesRead, &bytesWritten, &error); - gchar const *fn = local_fn; - - /* TODO: Replace the below fprintf's with something that does the right thing whether in - * gui or batch mode (e.g. --print=blah). Consider throwing an exception: currently one of - * the callers (sp_print_document_to_file, "ret = mod->begin(doc)") wrongly ignores the - * return code. - */ - if (fn != NULL) { - if (*fn == '|') { - fn += 1; - while (g_ascii_isspace(*fn)) fn += 1; -#ifndef WIN32 - osp = popen(fn, "w"); -#else - osp = _popen(fn, "w"); -#endif - if (!osp) { - fprintf(stderr, "inkscape: popen(%s): %s\n", - fn, strerror(errno)); - return 0; - } - _stream = _begin_stream = osp; - } else if (*fn == '>') { - fn += 1; - epsexport = g_str_has_suffix(fn,".eps"); - while (isspace(*fn)) fn += 1; - Inkscape::IO::dump_fopen_call(fn, "K"); - osf = Inkscape::IO::fopen_utf8name(fn, "w+"); - if (!osf) { - fprintf(stderr, "inkscape: fopen(%s): %s\n", - fn, strerror(errno)); - return 0; - } - _begin_stream = osf; - /* if font embedding is requested for EPS export... - * TODO:could be extended to PS export if texttopath=FALSE possible - */ - if(font_embedded && epsexport) - { - /** - * Create temporary file where to print the main "script" part of the EPS document. - * Use an extra stream (_begin_stream) to print the prolog and document setup sections. - * Thus, once all the (main) script part printed, all the fonts used are known and can be embedded - * just after the prolog section, in a Begin(End)Setup section (document setup), - * one Begin(End)Resource (DSC comment) section for each font embedded. - * Then, append the final script part from the temporary file (_stream in this case). - * Reference: Adobe Technical note 5001, "PostScript Document Struturing Conventions Specifications" - * page 19 - */ - osf_tmp = tmpfile(); - if(!osf_tmp) - { - g_warning("Could not create a temporary file for font embedding. Font embedding canceled."); - mod->set_param_bool("fontEmbedded", false); - font_embedded = false; - _stream = osf; - } else _stream = osf_tmp; - } else _stream = osf; - } else { - /* put cwd stuff in here */ - gchar *qn = ( *fn - ? g_strdup_printf("lpr -P %s", fn) /* FIXME: quote fn */ - : g_strdup("lpr") ); -#ifndef WIN32 - osp = popen(qn, "w"); -#else - osp = _popen(qn, "w"); -#endif - if (!osp) { - fprintf(stderr, "inkscape: popen(%s): %s\n", - qn, strerror(errno)); - return 0; - } - g_free(qn); - _stream = _begin_stream = osp; - } - } - - g_free(local_fn); - - if (_stream) { - /* fixme: this is kinda icky */ -#if !defined(_WIN32) && !defined(__WIN32__) - (void) signal(SIGPIPE, SIG_IGN); -#endif - } - - int const res = fprintf(_begin_stream, ( epsexport - ? "%%!PS-Adobe-3.0 EPSF-3.0\n" - : "%%!PS-Adobe-3.0\n" )); - /* flush this to test output stream as early as possible */ - if (fflush(_begin_stream)) { - /*g_print("caught error in sp_module_print_plain_begin\n");*/ - if (ferror(_begin_stream)) { - g_print("Error %d on output stream: %s\n", errno, - g_strerror(errno)); - } - g_print("Printing failed\n"); - /* fixme: should use pclose() for pipes */ - fclose(_begin_stream); - _begin_stream = NULL; - fflush(stdout); - return 0; - } - //TODO: do this same test on _stream - - // width and height in pt - _width = sp_document_width(doc) * PT_PER_PX; - _height = sp_document_height(doc) * PT_PER_PX; - - NRRect d; - bool pageBoundingBox; - bool pageLandscape; - pageBoundingBox = mod->get_param_bool("pageBoundingBox"); - // printf("Page Bounding Box: %s\n", pageBoundingBox ? "TRUE" : "FALSE"); - if (pageBoundingBox) { - d.x0 = d.y0 = 0; - d.x1 = ceil(_width); - d.y1 = ceil(_height); - } else { - SPItem* doc_item = SP_ITEM(sp_document_root(doc)); - sp_item_invoke_bbox(doc_item, &d, sp_item_i2r_affine(doc_item), TRUE); - // convert from px to pt - d.x0 *= PT_PER_PX; - d.x1 *= PT_PER_PX; - d.y0 *= PT_PER_PX; - d.y1 *= PT_PER_PX; - } - - Inkscape::SVGOStringStream os; - if (res >= 0) { - - os << "%%Creator: " << PACKAGE_STRING << "\n"; - // This will become problematic if inkscape gains the - // ability to handle multi paged documents. If this is - // the case the %%Orientation: comments should be - // renamed to %%PageOrientation: and moved to the - // respective pages. - os << "%%Pages: 1\n"; - - // 2004 Dec 10, BFC: - // The point of the following code is (1) to do the thing that's expected by users - // who have done File>New>A4_landscape or ...letter_landscape (i.e., rotate - // the output), while (2) not messing up users who simply want their output wider - // than it is tall (e.g., small figures for inclusion in LaTeX). - // The original patch by WQ only had the w>h condition. - { - double w = (d.x1 - d.x0); // width and height of bounding box, in pt - double h = (d.y1 - d.y0); - pageLandscape = ( - (w > 0. && h > 0.) // empty documents fail this sanity check, have w<0, h<0 - && (w > h) // implies, but does not prove, the user wanted landscape - && (w > 600) // approximate maximum printable width of an A4 - && (!epsexport) // eps should always be portrait - ) - ? true : false; - } - - if (pageLandscape) { - os << "%%Orientation: Landscape\n"; - os << "%%BoundingBox: " << (int) (_height - d.y1) << " " - << (int) d.x0 << " " - << (int) ceil(_height - d.y0) << " " - << (int) ceil(d.x1) << "\n"; - // According to Mike Sweet (the author of CUPS) - // HiResBoundingBox is only appropriate - // for EPS files. This means that we should - // distinguish if we export to ps or eps here. - // FIXME: I couldn't find HiResBoundingBox in the PS - // reference manual, so I guess we should skip - // it. - os << "%%HiResBoundingBox: " << (_height - d.y1) << " " - << d.x0 << " " - << (_height - d.y0) << " " - << d.x1 << "\n"; - if (!epsexport) { - os << "%%DocumentMedia: plain " - << (int) ceil(_height) << " " - << (int) ceil(_width) << " " - << "0 () ()\n"; - } - } else { - os << "%%Orientation: Portrait\n"; - os << "%%BoundingBox: " << (int) d.x0 << " " - << (int) d.y0 << " " - << (int) ceil(d.x1) << " " - << (int) ceil(d.y1) << "\n"; - os << "%%HiResBoundingBox: " << d.x0 << " " - << d.y0 << " " - << d.x1 << " " - << d.y1 << "\n"; - if (!epsexport) { - os << "%%DocumentMedia: plain " - << (int) ceil(_width) << " " - << (int) ceil(_height) << " " - << "0 () ()\n"; - } - } - - os << "%%EndComments\n"; - /* If font embedding requested, begin document setup section where to include font resources */ - if(font_embedded) os << "%%BeginSetup\n";/* Resume it later with Begin(End)Resource sections for font embedding. So, for now, we are done with the prolog/setup part. */ - gint ret = fprintf(_begin_stream, "%s", os.str().c_str()); - if(ret < 0) return ret; - - /* Main Script part (after document setup) begins */ - /* Empty os from all previous printing */ - std::string clrstr = ""; - os.str(clrstr); - // This will become problematic if we print multi paged documents: - os << "%%Page: 1 1\n"; - - if (pageLandscape) { - os << "90 rotate\n"; - if (_bitmap) { - os << "0 " << (int) -ceil(_height) << " translate\n"; - } - } else { - if (!_bitmap) { - os << "0 " << (int) ceil(_height) << " translate\n"; - } - } - - if (!_bitmap) { - os << PT_PER_PX << " " << -PT_PER_PX << " scale\n"; - // from now on we can output px, but they will be treated as pt - } - - /* As a new PS document is created, _fontlist has to be reinitialized (unref fonts from possible former PS docs) */ - _fonts = g_tree_new_full((GCompareDataFunc)strcmp, NULL, (GDestroyNotify)g_free, (GDestroyNotify)g_free); - } - - os << "0 0 0 setrgbcolor\n" - << "[] 0 setdash\n" - << "1 setlinewidth\n" - << "0 setlinejoin\n" - << "0 setlinecap\n"; - - /* FIXME: This function is declared to return unsigned, whereas fprintf returns a signed int * - * that can be zero if the first fprintf failed (os is empty) or "negative" (i.e. very positive - * in unsigned int interpretation) if the first fprintf failed but this one succeeds, or - * positive if both succeed. */ - return fprintf(_stream, "%s", os.str().c_str()); -} - -unsigned int -PrintPS::finish(Inkscape::Extension::Print *mod) -{ - if (!_stream) return 0; - - if (_bitmap) { - double const dots_per_pt = _dpi / PT_PER_IN; - - double const x0 = 0.0; - double const y0 = 0.0; - double const x1 = x0 + _width; - double const y1 = y0 + _height; - - /* Bitmap width/height in bitmap dots. */ - int const width = (int) (_width * dots_per_pt + 0.5); - int const height = (int) (_height * dots_per_pt + 0.5); - - Geom::Matrix affine; - affine[0] = width / ((x1 - x0) * PX_PER_PT); - affine[1] = 0.0; - affine[2] = 0.0; - affine[3] = height / ((y1 - y0) * PX_PER_PT); - affine[4] = -affine[0] * x0; - affine[5] = -affine[3] * y0; - - nr_arena_item_set_transform(mod->root, &affine); - - guchar *const px = g_new(guchar, 4 * width * 64); - - for (int y = 0; y < height; y += 64) { - /* Set area of interest. */ - NRRectL bbox; - bbox.x0 = 0; - bbox.y0 = y; - bbox.x1 = width; - bbox.y1 = MIN(height, y + 64); - - /* Update to renderable state. */ - NRGC gc(NULL); - gc.transform.setIdentity(); - nr_arena_item_invoke_update(mod->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); - /* Render */ - /* This should take guchar* instead of unsigned char*) */ - NRPixBlock pb; - nr_pixblock_setup_extern(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, - bbox.x0, bbox.y0, bbox.x1, bbox.y1, - (guchar*)px, 4 * width, FALSE, FALSE); - memset(px, 0xff, 4 * width * 64); - nr_arena_item_invoke_render(NULL, mod->root, &bbox, &pb, 0); - /* Blitter goes here */ - Geom::Matrix imgt; - imgt[0] = (bbox.x1 - bbox.x0) / dots_per_pt; - imgt[1] = 0.0; - imgt[2] = 0.0; - imgt[3] = (bbox.y1 - bbox.y0) / dots_per_pt; - imgt[4] = 0.0; - imgt[5] = _height - y / dots_per_pt - (bbox.y1 - bbox.y0) / dots_per_pt; - - print_image(_stream, px, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0, 4 * width, &imgt); - } - - g_free(px); - } - - fprintf(_stream, "showpage\n"); - int const res = fprintf(_stream, "%%%%EOF\n"); - - /* Flush stream to be sure. */ - (void) fflush(_stream); - - char c; - /* If font embedding... */ - if(mod->get_param_bool("fontEmbedded")) - { - /* Close the document setup section that had been started (because all the needed resources are supposed to be included now) */ - /*res = */fprintf(_begin_stream, "%s", "%%EndSetup\n"); - /* If font embedding requested, the following PS script part was printed to a different file from the prolog/setup, so script part (current _stream) needs to be copied to prolog/setup file to get the complete (E)PS document */ - if(fseek(_stream, 0, SEEK_SET) == 0) - { - while((c = fgetc(_stream))!=EOF) fputc(c, _begin_stream); - } - fclose(_stream); - _stream = _begin_stream; - } - - /* fixme: should really use pclose for popen'd streams */ - fclose(_stream); - _stream = NULL; - - _latin1_encoded_fonts.clear(); - - g_tree_destroy(_fonts); - - return res; -} - -unsigned int -PrintPS::bind(Inkscape::Extension::Print */*mod*/, Geom::Matrix const *transform, float /*opacity*/) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - Inkscape::SVGOStringStream os; - os << "gsave [" << (*transform)[0] << " " - << (*transform)[1] << " " - << (*transform)[2] << " " - << (*transform)[3] << " " - << (*transform)[4] << " " - << (*transform)[5] << "] concat\n"; - - return fprintf(_stream, "%s", os.str().c_str()); -} - -unsigned int -PrintPS::release(Inkscape::Extension::Print */*mod*/) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - return fprintf(_stream, "grestore\n"); -} - -unsigned int -PrintPS::comment(Inkscape::Extension::Print */*mod*/, char const *comment) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - return fprintf(_stream, "%%! %s\n",comment); -} - -void -PrintPS::print_fill_style(SVGOStringStream &os, SPStyle const *const style, NRRect const *pbox) -{ - g_return_if_fail( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ); - - if (style->fill.isColor()) { - float rgb[3]; - sp_color_get_rgb_floatv(&style->fill.value.color, rgb); - - os << rgb[0] << " " << rgb[1] << " " << rgb[2] << " setrgbcolor\n"; - - } else { - g_assert( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ); - - if (SP_IS_LINEARGRADIENT(SP_STYLE_FILL_SERVER(style))) { - - SPLinearGradient *lg = SP_LINEARGRADIENT(SP_STYLE_FILL_SERVER(style)); - Geom::Point p1 (lg->x1.computed, lg->y1.computed); - Geom::Point p2 (lg->x2.computed, lg->y2.computed); - if (pbox && SP_GRADIENT(lg)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - // convert to userspace - Geom::Matrix bbox2user(pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); - p1 *= bbox2user; - p2 *= bbox2user; - } - - os << "<<\n/ShadingType 2\n/ColorSpace /DeviceRGB\n"; - os << "/Coords [" << p1[Geom::X] << " " << p1[Geom::Y] << " " << p2[Geom::X] << " " << p2[Geom::Y] <<"]\n"; - os << "/Extend [true true]\n"; - os << "/Domain [0 1]\n"; - os << "/Function <<\n/FunctionType 3\n/Functions\n[\n"; - - sp_gradient_ensure_vector(SP_GRADIENT(lg)); // when exporting from commandline, vector is not built - for (unsigned i = 0; i + 1 < lg->vector.stops.size(); i++) { - float rgb[3]; - sp_color_get_rgb_floatv(&lg->vector.stops[i].color, rgb); - os << "<<\n/FunctionType 2\n/Domain [0 1]\n"; - os << "/C0 [" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "]\n"; - sp_color_get_rgb_floatv(&lg->vector.stops[i+1].color, rgb); - os << "/C1 [" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "]\n"; - os << "/N 1\n>>\n"; - } - os << "]\n/Domain [0 1]\n"; - os << "/Bounds [ "; - for (unsigned i = 0; i + 2 < lg->vector.stops.size(); i++) { - os << lg->vector.stops[i+1].offset <<" "; - } - os << "]\n"; - os << "/Encode [ "; - for (unsigned i = 0; i + 1 < lg->vector.stops.size(); i++) { - os << "0 1 "; - } - os << "]\n"; - os << ">>\n>>\n"; - - } else if (SP_IS_RADIALGRADIENT(SP_STYLE_FILL_SERVER(style))) { - - SPRadialGradient *rg = SP_RADIALGRADIENT(SP_STYLE_FILL_SERVER(style)); - Geom::Point c(rg->cx.computed, rg->cy.computed); - Geom::Point f(rg->fx.computed, rg->fy.computed); - double r = rg->r.computed; - if (pbox && SP_GRADIENT(rg)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - // convert to userspace - Geom::Matrix const bbox2user(pbox->x1 - pbox->x0, 0, - 0, pbox->y1 - pbox->y0, - pbox->x0, pbox->y0); - c *= bbox2user; - f *= bbox2user; - r *= bbox2user.descrim(); - } - - os << "<<\n/ShadingType 3\n/ColorSpace /DeviceRGB\n"; - os << "/Coords ["<< f[Geom::X] <<" "<< f[Geom::Y] <<" 0 "<< c[Geom::X] <<" "<< c[Geom::Y] <<" "<< r <<"]\n"; - os << "/Extend [true true]\n"; - os << "/Domain [0 1]\n"; - os << "/Function <<\n/FunctionType 3\n/Functions\n[\n"; - - sp_gradient_ensure_vector(SP_GRADIENT(rg)); // when exporting from commandline, vector is not built - for (unsigned i = 0; i + 1 < rg->vector.stops.size(); i++) { - float rgb[3]; - sp_color_get_rgb_floatv(&rg->vector.stops[i].color, rgb); - os << "<<\n/FunctionType 2\n/Domain [0 1]\n"; - os << "/C0 [" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "]\n"; - sp_color_get_rgb_floatv(&rg->vector.stops[i+1].color, rgb); - os << "/C1 [" << rgb[0] << " " << rgb[1] << " " << rgb[2] << "]\n"; - os << "/N 1\n>>\n"; - } - os << "]\n/Domain [0 1]\n"; - os << "/Bounds [ "; - for (unsigned i = 0; i + 2 < rg->vector.stops.size(); i++) { - os << rg->vector.stops[i+1].offset << " "; - } - os << "]\n"; - os << "/Encode [ "; - for (unsigned i = 0; i + 1 < rg->vector.stops.size(); i++) { - os << "0 1 "; - } - os << "]\n"; - os << ">>\n>>\n"; - } - } -} - -void -PrintPS::print_stroke_style(SVGOStringStream &os, SPStyle const *style) -{ - float rgb[3]; - sp_color_get_rgb_floatv(&style->stroke.value.color, rgb); - - os << rgb[0] << " " << rgb[1] << " " << rgb[2] << " setrgbcolor\n"; - - // There are rare cases in which for a solid line stroke_dasharray_set is true. To avoid - // invalid PS-lines such as "[0.0000000 0.0000000] 0.0000000 setdash", which should be "[] 0 setdash", - // we first check if all components of stroke_dash.dash are 0. - bool LineSolid = true; - if (style->stroke_dash.n_dash && - style->stroke_dash.dash ) - { - int i = 0; - while (LineSolid && (i < style->stroke_dash.n_dash)) { - if (style->stroke_dash.dash[i] > 0.00000001) - LineSolid = false; - i++; - } - if (!LineSolid) { - os << "["; - for (i = 0; i < style->stroke_dash.n_dash; i++) { - if (i > 0) { - os << " "; - } - os << style->stroke_dash.dash[i]; - } - os << "] " << style->stroke_dash.offset << " setdash\n"; - } else { - os << "[] 0 setdash\n"; - } - } else { - os << "[] 0 setdash\n"; - } - - os << style->stroke_width.computed << " setlinewidth\n"; - os << style->stroke_linejoin.computed << " setlinejoin\n"; - os << style->stroke_linecap.computed << " setlinecap\n"; -} - - -unsigned int -PrintPS::fill(Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *const style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - if ( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) - { - Inkscape::SVGOStringStream os; - - os << "gsave\n"; - - print_fill_style(os, style, pbox); - - print_pathvector(os, pathv); - - if (style->fill_rule.computed == SP_WIND_RULE_EVENODD) { - if (style->fill.isColor()) { - os << "eofill\n"; - } else { - g_assert( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ); - SPGradient const *g = SP_GRADIENT(SP_STYLE_FILL_SERVER(style)); - os << "eoclip\n"; - if (g->gradientTransform_set) { - os << "gsave [" << g->gradientTransform[0] << " " << g->gradientTransform[1] - << " " << g->gradientTransform[2] << " " << g->gradientTransform[3] - << " " << g->gradientTransform[4] << " " << g->gradientTransform[5] << "] concat\n"; - } - os << "shfill\n"; - if (g->gradientTransform_set) { - os << "grestore\n"; - } - } - } else { - if (style->fill.isColor()) { - os << "fill\n"; - } else { - g_assert( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ); - SPGradient const *g = SP_GRADIENT(SP_STYLE_FILL_SERVER(style)); - os << "clip\n"; - if (g->gradientTransform_set) { - os << "gsave [" << g->gradientTransform[0] << " " << g->gradientTransform[1] - << " " << g->gradientTransform[2] << " " << g->gradientTransform[3] - << " " << g->gradientTransform[4] << " " << g->gradientTransform[5] << "] concat\n"; - } - os << "shfill\n"; - if (g->gradientTransform_set) { - os << "grestore\n"; - } - } - } - - os << "grestore\n"; - - fprintf(_stream, "%s", os.str().c_str()); - } - - return 0; -} - - -unsigned int -PrintPS::stroke(Inkscape::Extension::Print *mod, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - if (style->stroke.isColor()) { - Inkscape::SVGOStringStream os; - - print_stroke_style(os, style); - - print_pathvector(os, pathv); - - os << "stroke\n"; - - fprintf(_stream, "%s", os.str().c_str()); - } - - return 0; -} - -unsigned int -PrintPS::image(Inkscape::Extension::Print *mod, guchar *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *transform, SPStyle const *style) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - return print_image(_stream, px, w, h, rs, transform); -} - -/* PSFontName is now useless (cf. text() method code) */ -char const * -PrintPS::PSFontName(SPStyle const *style) -{ - font_instance *tf = font_factory::Default()->FaceFromStyle(style); - - char const *n; - char name_buf[256]; - - // PS does not like spaces in fontnames, replace them with the usual dashes. - - if (tf) { - tf->PSName(name_buf, sizeof(name_buf)); - n = g_strdelimit(name_buf, " ", '-'); - tf->Unref(); - } else { - // this system does not have this font, so just use the name from SVG in the hope that PS interpreter will make sense of it - bool i = (style->font_style.value == SP_CSS_FONT_STYLE_ITALIC); - bool o = (style->font_style.value == SP_CSS_FONT_STYLE_OBLIQUE); - bool b = (style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLD) || - (style->font_weight.value >= SP_CSS_FONT_WEIGHT_500 && style->font_weight.value <= SP_CSS_FONT_WEIGHT_900); - - n = g_strdup_printf("%s%s%s%s", - g_strdelimit(style->text->font_family.value, " ", '-'), - (b || i || o) ? "-" : "", - (b) ? "Bold" : "", - (i) ? "Italic" : ((o) ? "Oblique" : "") ); - } - - return g_strdup(n); -} - -//LSB = Least Significant Byte -//converts 4-byte array to "LSB first" to "LSB last" -/** -* (Used by PrintPS::embed_t1 (from libgnomeprint/gnome-font-face.c), -* to get the length of data segment (bytes 3-6 in IBM PC (PostScript) font file format. -* Reference: Adobe technical note 5040, "Supporting Downloadable PostScript -* Language Fonts", page 9) -*/ - -#define INT32_LSB_2_5(q) ((q)[2] + ((q)[3] << 8) + ((q)[4] << 16) + ((q)[5] << 24)) - -/** -* \brief For "Type 1" font only, print font data in output stream, to embed font data in PS output. -* \param os Stream of output. -* \param font Font whose data to embed. -* \return FALSE if font embedding canceled (due to error or not supported font type), TRUE otherwise -* TODO: enable font embedding for True Type -*/ -//adapted more/less from libgnomeprint/gnome_font_face_ps_embed_t1() -bool -PrintPS::embed_t1 (SVGOStringStream &os, font_instance* font) -{ - //check font type - FT_Face font_face = pango_ft2_font_get_face(font->pFont); - const FT_String* font_type = FT_Get_X11_Font_Format(font_face); - g_return_val_if_fail (_fontTypesMap[font_type] == FONT_TYPE1, false); - //get font filename, stream to font file and size - FT_Stream font_stream = font_face->stream; - const char* font_filename = (char*) font_stream->pathname.pointer; - unsigned long font_stream_size = font_stream->size; - //first detect if font file is in IBM PC format - /** - * if first byte is 0x80, font file is pfb, do the same as a pfb to pfa converter - * Reference: Adobe technical note 5040, "Supporting Downloadable PostScript - * Language Fonts", page 9 - * else: include all the ASCII data in the font pfa file - **/ - char* buf = new char[7]; - unsigned char* buffer = new unsigned char[7];//for the 6 header bytes (data segment length is unknown at this point) and final '\0' - std::string ascii_data;//for data segment "type 1" in IBM PC Format - //read the 6 header bytes - //for debug: g_warning("Reading from font file %s...", font_filename); - font_stream->close(font_stream); - ifstream font_file (font_filename, ios::in|ios::binary); - if (!font_file.is_open()) { - g_warning ("file %s: line %d: Cannot open font file %s", __FILE__, __LINE__, font_filename); - return false; - } - font_file.read(buf, 6); - buffer = (unsigned char*) buf; - - //If font file is pfb, do the same as pfb to pfa converter - //check byte 1 - if (buffer[0] == 0x80) { - const char hextab[17] = "0123456789abcdef"; - unsigned long offset = 0; - - while (offset < font_stream_size) { - gint length, i; - if (buffer[0] != 0x80) { - g_warning ("file %s: line %d: Corrupt %s", __FILE__, __LINE__, font_filename); - //TODO: print some default font data anyway like libgnomeprint/gnome_font_face_ps_embed_empty - return false; - } - switch (buffer[1]) { - case 1: - //get data segment length from bytes 3-6 - //(Note: byte 1 is first byte in comments to match Adobe technical note 5040, but index 0 in code) - length = INT32_LSB_2_5 (buffer); - offset += 6; - //resize the buffer to fit the data segment length - delete [] buf; - buf = new char[length + 1]; - buffer = new unsigned char[length + 1]; - //read and print all the data segment length - font_file.read(buf, length); - buffer = (unsigned char*) buf; - /** - * Assigning a part from the buffer of length "length" ensures - * that no incorrect extra character will be printed and make the PS output invalid - * That was the case with the code: - * os << buffer; - * (A substring method could have been used as well.) - */ - ascii_data.assign(buf, 0, length); - os << ascii_data; - offset += length; - //read next 6 header bytes - font_file.read(buf, 6); - break; - case 2: - length = INT32_LSB_2_5 (buffer); - offset += 6; - //resize the buffer to fit the data segment length - delete [] buf; - buf = new char[length + 1]; - buffer = new unsigned char[length + 1]; - //read and print all the data segment length - font_file.read(buf, length); - buffer = (unsigned char*) buf; - for (i = 0; i < length; i++) { - os << hextab[buffer[i] >> 4]; - os << hextab[buffer[i] & 15]; - offset += 1; - if ((i & 31) == 31 || i == length - 1) - os << "\n"; - } - //read next 6 header bytes - font_file.read(buf, 6); - break; - case 3: - /* Finished */ - os << "\n"; - offset = font_stream_size; - break; - default: - os << "%%%ERROR: Font file corrupted at byte " << offset << "\n"; - //TODO: print some default font data anyway like libgnomeprint/gnome_font_face_ps_embed_empty - return false; - } - } - } - //else: font file is pfa, include all directly - else { - //font is not in IBM PC format, all the file content can be directly printed - //resize buffer - delete [] buf; - buf = new char[font_stream_size + 1]; - delete [] buffer; - font_file.seekg (0, ios::beg); - font_file.read(buf, font_stream_size); - /** - * Assigning a part from the buffer of length "length" ensures - * that no incorrect extra character will be printed and make the PS output invalid - * That was the case with the code: - * os << buffer; - * (A substring method could have been used as well.) - */ - ascii_data.assign(buf, 0, font_stream_size); - os << ascii_data; - } - font_file.close(); - delete [] buf; - buf = NULL; - buffer = NULL;// Clear buffer to prevent using invalid memory reference. - - char font_psname[256]; - font->PSName(font_psname, sizeof(font_psname)); - FT_Long font_num_glyphs = font_face->num_glyphs; - if (font_num_glyphs < 256) { - gint glyph; - /* 8-bit vector */ - os << "(" << font_psname << ") cvn findfont dup length dict begin\n"; - os << "{1 index /FID ne {def} {pop pop} ifelse} forall\n"; - os << "/Encoding [\n"; - for (glyph = 0; glyph < 256; glyph++) { - guint g; - gchar c[256]; - FT_Error status; - g = (glyph < font_num_glyphs) ? glyph : 0; - status = FT_Get_Glyph_Name (font_face, g, c, 256); - - if (status != FT_Err_Ok) { - g_warning ("file %s: line %d: Glyph %d has no name in %s", __FILE__, __LINE__, g, font_filename); - g_snprintf (c, 256, ".notdef"); - } - - os << "/" << c << ( ((glyph & 0xf) == 0xf)?"\n":" " ); - } - os << "] def currentdict end\n"; - //TODO: manage several font instances for same ps name like in libgnomeprint/gnome_print_ps2_set_font_real() - //gf_pso_sprintf (pso, "(%s) cvn exch definefont pop\n", pso->encodedname); - os << "(" << font_psname << ") cvn exch definefont pop\n"; - } else { - gint nfonts, i, j; - /* 16-bit vector */ - nfonts = (font_num_glyphs + 255) >> 8; - - os << "32 dict begin\n"; - /* Common entries */ - os << "/FontType 0 def\n"; - os << "/FontMatrix [1 0 0 1 0 0] def\n"; - os << "/FontName (" << font_psname << "-Glyph-Composite) cvn def\n"; - os << "/LanguageLevel 2 def\n"; - - /* Type 0 entries */ - os << "/FMapType 2 def\n"; - - /* Bitch 'o' bitches */ - os << "/FDepVector [\n"; - - for (i = 0; i < nfonts; i++) { - os << "(" << font_psname << ") cvn findfont dup length dict begin\n"; - os << "{1 index /FID ne {def} {pop pop} ifelse} forall\n"; - os << "/Encoding [\n"; - for (j = 0; j < 256; j++) { - gint glyph; - gchar c[256]; - FT_Error status; - glyph = 256 * i + j; - if (glyph >= font_num_glyphs) - glyph = 0; - status = FT_Get_Glyph_Name (font_face, glyph, c, 256); - if (status != FT_Err_Ok) { - g_warning ("file %s: line %d: Glyph %d has no name in %s", __FILE__, __LINE__, glyph, font_filename); - g_snprintf (c, 256, ".notdef"); - } - os << "/" << c << ( ((j & 0xf) == 0xf)?"\n":" " ); - } - os << "] def\n"; - os << "currentdict end (" << font_psname << "-Glyph-Page-"; - os << std::dec << i; - os << ") cvn exch definefont\n"; - } - os << "] def\n"; - os << "/Encoding [\n"; - for (i = 0; i < 256; i++) { - gint fn; - fn = (i < nfonts) ? i : 0; - os << std::dec << fn; - os << ( ((i & 0xf) == 0xf) ? "\n" : " " ); - } - os << "] def\n"; - os << "currentdict end\n"; - //TODO: manage several font instances for same ps name like in libgnomeprint/gnome_print_ps2_set_font_real() - //gf_pso_sprintf (pso, "(%s) cvn exch definefont pop\n", pso->encodedname); - os << "(" << font_psname << ") cvn exch definefont pop\n"; - } - //font embedding completed - return true; -} - - - -/** -* \brief Print font data in output stream, to embed font data in PS output. -* \param os Stream of output. -* \param font Font whose data to embed. -* \return FALSE if font embedding canceled (due to error or not supported font type), TRUE otherwise -*/ -//adapted from libgnomeprint/gnome_font_face_ps_embed() -bool PrintPS::embed_font(SVGOStringStream &os, font_instance* font) -{ - //Hinted at by a comment in libgnomeprint/fcpattern_to_gp_font_entry() - //Determining the font type in the "Pango way" - FT_Face font_face = pango_ft2_font_get_face(font->pFont); - const FT_String* font_type = FT_Get_X11_Font_Format(font_face); - - /** - * Possible values of "font_type": Type 1, TrueType, etc. - * Embedding available only for Type 1 fonts so far. - */ - //TODO: provide support for other font types (TrueType is a priority) - switch(_fontTypesMap[font_type]) - { - case FONT_TYPE1: - return embed_t1 (os, font); - //TODO: implement TT font embedding - /*case FONT_TRUETYPE: - embed_tt (os, font); - break;*/ - default: - g_warning("Unknown (not supported) font type for embedding: %s", font_type); - //TODO: embed something like in libgnomeprint/gnome_font_face_ps_embed_empty(); - return false; - } -} - - -/** -* \brief Converts UTF-8 string to sequence of glyph numbers for PostScript string (cf. "show" commands.). -* \param os Stream of output. -* \param font Font used for unicode->glyph mapping. -* \param unistring UTF-8 encoded string to convert. -*/ -void PrintPS::print_glyphlist(SVGOStringStream &os, font_instance* font, Glib::ustring unistring) -{ - //iterate through unicode chars in unistring - Glib::ustring::iterator unistring_iter; - gunichar unichar; - gint glyph_index, glyph_page; - - FT_Face font_face = pango_ft2_font_get_face(font->pFont); - FT_Long font_num_glyphs = font_face->num_glyphs; - //whether font has more than one glyph pages (16-bit encoding) - bool two_bytes_encoded = (font_num_glyphs > 255); - - for (unistring_iter = unistring.begin(); unistring_iter!=unistring.end(); unistring_iter++) - { - //get unicode char - unichar = *unistring_iter; - //get matching glyph index in current font for unicode char - //default glyph index is 0 for undefined font character (glyph unavailable) - //TODO: if glyph unavailable for current font, use a default font among the most Unicode-compliant - e.g. Bitstream Cyberbit - I guess - glyph_index = font->MapUnicodeChar(unichar); - //if more than one glyph pages for current font (16-bit encoding), - if(two_bytes_encoded) - { - //add glyph page before glyph index. - glyph_page = (glyph_index >> 8) & 0xff; - os << "\\"; - //convert in octal code before printing - os << std::oct << glyph_page; - } - //(If one page - 8-bit encoding -, nothing to add.) - //TODO: explain the following line inspired from libgnomeprint/gnome_print_ps2_glyphlist() - glyph_index = glyph_index & 0xff; - //TODO: mark glyph as used for current font, if Inkscape has to embed minimal font data in PS - os << "\\"; - //convert in octal code before printing - os << std::oct << glyph_index; - } -} - -unsigned int -PrintPS::text(Inkscape::Extension::Print *mod, char const *text, Geom::Point p, - SPStyle const *const style) -{ - if (!_stream) return 0; // XXX: fixme, returning -1 as unsigned. - if (_bitmap) return 0; - - //check whether fonts have to be embedded in the PS output - //if not, use the former way of Inkscape to print text - gboolean font_embedded = mod->fontEmbedded(); - - Inkscape::SVGOStringStream os; - //find font - /** - * A font_instance object is necessary for the next steps, - * that's why using PSFontName() method just to get the PS fontname - * is not enough and not appropriate - */ - font_instance *tf = font_factory::Default()->FaceFromStyle(style); - - const gchar *fn = NULL; - char name_buf[256]; - - //check whether font was found - /** - * This check is not strictly reliable - * since Inkscape returns a default font if font not found. - * This is just to be consistent with the method PSFontName(). - */ - if (tf) { - //get font PS name - tf->PSName(name_buf, sizeof(name_buf)); - fn = name_buf; - } else { - // this system does not have this font, so cancel font embedding... - font_embedded = FALSE; - //this case seems to never happen since Inkscape uses a default font instead (like BitstreamVeraSans on Windows) - g_warning("Font %s not found.", fn); - //...and just use the name from SVG in the hope that PS interpreter will make sense of it - bool i = (style->font_style.value == SP_CSS_FONT_STYLE_ITALIC); - bool o = (style->font_style.value == SP_CSS_FONT_STYLE_OBLIQUE); - bool b = (style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLD) || - (style->font_weight.value >= SP_CSS_FONT_WEIGHT_500 && style->font_weight.value <= SP_CSS_FONT_WEIGHT_900); - - fn = g_strdup_printf("%s%s%s%s", - g_strdelimit(style->text->font_family.value, " ", '-'), - (b || i || o) ? "-" : "", - (b) ? "Bold" : "", - (i) ? "Italic" : ((o) ? "Oblique" : "") ); - } - - /** - * If font embedding is requested, tempt to embed the font the first time it is used, once and for all. - * There is no selection of the glyph descriptions to embed, based on the characters used effectively in the document. - * (TODO?) - * Else, back to the former way of printing. - */ - gpointer is_embedded; - //if not first time the font is used and if font embedding requested, check whether the font has been embedded (successfully the first time). - if(g_tree_lookup_extended(_fonts, fn, NULL, &is_embedded)) font_embedded = font_embedded && (strcmp((char *)is_embedded, "TRUE") == 0); - else - { - //first time the font is used - if(font_embedded) - { - //embed font in PS output - //adapted from libgnomeprint/gnome_print_ps2_close() - os << "%%BeginResource: font " << fn << "\n"; - font_embedded = embed_font(os, tf); - os << "%%EndResource: font " << fn << "\n"; - if(!font_embedded) g_warning("Font embedding canceled for font: %s", fn); - else fprintf(_begin_stream, "%s", os.str().c_str()); - //empty os before resume printing to the script stream - std::string clrstr = ""; - os.str(clrstr); - - } - //add to the list - g_tree_insert(_fonts, g_strdup(fn), g_strdup((font_embedded)?"TRUE":"FALSE")); - } - - Glib::ustring s; - // Escape chars - Inkscape::SVGOStringStream escaped_text; - //if font embedding, all characters will be converted to glyph indices (cf. PrintPS::print_glyphlist()), - //so no need to escape characters - //else back to the old way, i.e. escape chars: '\',')','(' and UTF-8 ones - if(font_embedded) s = text; - else { - escaped_text << std::oct; - for (gchar const *p_text = text ; *p_text ; p_text = g_utf8_next_char(p_text)) { - gunichar const c = g_utf8_get_char(p_text); - if (c == '\\' || c == ')' || c == '(') - escaped_text << '\\' << static_cast<char>(c); - else if (c >= 0x80) - escaped_text << '\\' << c; - else - escaped_text << static_cast<char>(c); - } - } - - os << "gsave\n"; - - // set font - if(font_embedded) os << "/" << fn << " findfont\n"; - else { - if (_latin1_encoded_fonts.find(fn) == _latin1_encoded_fonts.end()) { - if (!_newlatin1font_proc_defined) { - // input: newfontname, existingfontname - // output: new font object, also defined to newfontname - os << "/newlatin1font " // name of the proc - "{findfont dup length dict copy " // load the font and create a copy of it - "dup /Encoding ISOLatin1Encoding put " // change the encoding in the copy - "definefont} def\n"; // create the new font and leave it on the stack, define the proc - _newlatin1font_proc_defined = true; - } - if(strchr(fn, ' ') == NULL) - os << "/" << fn << "-ISOLatin1 /" << fn << " newlatin1font\n"; - else - os << "(/" << fn << "-ISOLatin1) (/" << fn << ") newlatin1font\n"; - _latin1_encoded_fonts.insert(fn); - } else - if(strchr(fn, ' ') == NULL) - os << "/" << fn << "-ISOLatin1 findfont\n"; - else - os << "(/" << fn << "-ISOLatin1) findfont\n"; - } - os << style->font_size.computed << " scalefont\n"; - os << "setfont\n"; - //The commented line beneath causes Inkscape to crash under Linux but not under Windows - //g_free((void*) fn); - - if ( style->fill.isColor() - || ( style->fill.isPaintserver() - && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) - { - // set fill style - print_fill_style(os, style, NULL); - // FIXME: we don't know the pbox of text, so have to pass NULL. This means gradients with - // bbox units won't work with text. However userspace gradients don't work with text either - // (text is black) for some reason. - - os << "newpath\n"; - os << p[Geom::X] << " " << p[Geom::Y] << " moveto\n"; - os << "("; - if(font_embedded) print_glyphlist(os, tf, s); - else os << escaped_text.str(); - os << ") show\n"; - } - - if (style->stroke.isColor()) { - - // set stroke style - print_stroke_style(os, style); - - // paint stroke - os << "newpath\n"; - os << p[Geom::X] << " " << p[Geom::Y] << " moveto\n"; - os << "("; - if(font_embedded) print_glyphlist(os, tf, s); - else os << escaped_text.str(); - os << ") false charpath stroke\n"; - } - - if(tf) tf->Unref(); - - os << "grestore\n"; - - fprintf(_stream, "%s", os.str().c_str()); - - return 0; -} - - - -/* PostScript helpers */ - -void -PrintPS::print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv) -{ - if (pathv.empty()) - return; - - os << "newpath\n"; - - for(Geom::PathVector::const_iterator it = pathv.begin(); it != pathv.end(); ++it) { - - os << it->initialPoint()[Geom::X] << " " << it->initialPoint()[Geom::Y] << " moveto\n"; - - for(Geom::Path::const_iterator cit = it->begin(); cit != it->end_open(); ++cit) { - print_2geomcurve(os, *cit); - } - - if (it->closed()) { - os << "closepath\n"; - } - - } -} - -void -PrintPS::print_2geomcurve(SVGOStringStream &os, Geom::Curve const & c ) -{ - using Geom::X; - using Geom::Y; - - if( is_straight_curve(c) ) - { - os << c.finalPoint()[X] << " " << c.finalPoint()[Y] << " lineto\n"; - } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const*>(&c)) { - std::vector<Geom::Point> points = cubic_bezier->points(); - os << points[1][X] << " " << points[1][Y] << " " - << points[2][X] << " " << points[2][Y] << " " - << points[3][X] << " " << points[3][Y] << " curveto\n"; - } - else { - //this case handles sbasis as well as all other curve types - Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(c.toSBasis(), 0.1); - - for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { - print_2geomcurve(os, *iter); - } - } -} - - -/* The following code is licensed under GNU GPL. -** The packbits, ascii85 and imaging printing code -** is from the gimp's postscript.c. -*/ - -/** -* \param nin Number of bytes of source data. -* \param src Source data. -* \param nout Number of output bytes. -* \param dst Buffer for output. -*/ -void -PrintPS::compress_packbits(int nin, - guchar *src, - int *nout, - guchar *dst) - -{ - register guchar c; - int nrepeat, nliteral; - guchar *run_start; - guchar *start_dst = dst; - guchar *last_literal = NULL; - - for (;;) { - if (nin <= 0) break; - - run_start = src; - c = *run_start; - - /* Search repeat bytes */ - if ((nin > 1) && (c == src[1])) { - nrepeat = 1; - nin -= 2; - src += 2; - while ((nin > 0) && (c == *src)) { - nrepeat++; - src++; - nin--; - if (nrepeat == 127) break; /* Maximum repeat */ - } - - /* Add two-byte repeat to last literal run ? */ - if ( (nrepeat == 1) - && (last_literal != NULL) && (((*last_literal)+1)+2 <= 128) ) - { - *last_literal += 2; - *(dst++) = c; - *(dst++) = c; - continue; - } - - /* Add repeat run */ - *(dst++) = (guchar)((-nrepeat) & 0xff); - *(dst++) = c; - last_literal = NULL; - continue; - } - /* Search literal bytes */ - nliteral = 1; - nin--; - src++; - - for (;;) { - if (nin <= 0) break; - - if ((nin >= 2) && (src[0] == src[1])) /* A two byte repeat ? */ - break; - - nliteral++; - nin--; - src++; - if (nliteral == 128) break; /* Maximum literal run */ - } - - /* Could be added to last literal run ? */ - if ((last_literal != NULL) && (((*last_literal)+1)+nliteral <= 128)) { - *last_literal += nliteral; - } else { - last_literal = dst; - *(dst++) = (guchar)(nliteral-1); - } - while (nliteral-- > 0) *(dst++) = *(run_start++); - } - *nout = dst - start_dst; -} - -void -PrintPS::ascii85_init(void) -{ - ascii85_len = 0; - ascii85_linewidth = 0; -} - -void -PrintPS::ascii85_flush(SVGOStringStream &os) -{ - char c[5]; - bool const zero_case = (ascii85_buf == 0); - static int const max_linewidth = 75; - - for (int i = 4; i >= 0; i--) { - c[i] = (ascii85_buf % 85) + '!'; - ascii85_buf /= 85; - } - /* check for special case: "!!!!!" becomes "z", but only if not - * at end of data. */ - if (zero_case && (ascii85_len == 4)) { - if (ascii85_linewidth >= max_linewidth) { - os << '\n'; - ascii85_linewidth = 0; - } - os << 'z'; - ascii85_linewidth++; - } else { - for (int i = 0; i < ascii85_len+1; i++) { - if ((ascii85_linewidth >= max_linewidth) && (c[i] != '%')) { - os << '\n'; - ascii85_linewidth = 0; - } - os << c[i]; - ascii85_linewidth++; - } - } - - ascii85_len = 0; - ascii85_buf = 0; -} - -inline void -PrintPS::ascii85_out(guchar byte, SVGOStringStream &os) -{ - if (ascii85_len == 4) - ascii85_flush(os); - - ascii85_buf <<= 8; - ascii85_buf |= byte; - ascii85_len++; -} - -void -PrintPS::ascii85_nout(int n, guchar *uptr, SVGOStringStream &os) -{ - while (n-- > 0) { - ascii85_out(*uptr, os); - uptr++; - } -} - -void -PrintPS::ascii85_done(SVGOStringStream &os) -{ - if (ascii85_len) { - /* zero any unfilled buffer portion, then flush */ - ascii85_buf <<= (8 * (4-ascii85_len)); - ascii85_flush(os); - } - - os << "~>\n"; -} - -unsigned int -PrintPS::print_image(FILE *ofp, guchar *px, unsigned int width, unsigned int height, unsigned int rs, - Geom::Matrix const *transform) -{ - Inkscape::SVGOStringStream os; - - os << "gsave\n"; - - os << "[" << (*transform)[0] << " " - << (*transform)[1] << " " - << (*transform)[2] << " " - << (*transform)[3] << " " - << (*transform)[4] << " " - << (*transform)[5] << "] concat\n"; - - /* Write read image procedure */ - os << "<<\n"; - os << " /ImageType 3\n"; - os << " /InterleaveType 1\n"; - - os << " /MaskDict\n"; - os << " <<\n"; - os << " /ImageType 1\n"; - os << " /Width " << width << "\n"; - os << " /Height " << height << "\n"; - os << " /ImageMatrix " - << "[" << width << " " - << 0 << " " - << 0 << " " - << -((long) height) << " " - << 0 << " " - << height << "]\n"; - os << " /BitsPerComponent 8\n"; - os << " /Decode [1 0]\n"; - os << " >>\n"; - - os << " /DataDict\n"; - os << " <<\n"; - os << " /ImageType 1\n"; - os << " /Width " << width << "\n"; - os << " /Height " << height << "\n"; - os << " /ImageMatrix " - << "[" << width << " " - << 0 << " " - << 0 << " " - << -((long )height) << " " - << 0 << " " - << height << "]\n"; - os << " /DataSource currentfile /ASCII85Decode filter\n"; - os << " /BitsPerComponent 8\n"; - os << " /Decode [0 1 0 1 0 1]\n"; - os << " >>\n"; - - os << ">>\n"; - - /* Allocate buffer for packbits data. Worst case: Less than 1% increase */ - guchar *const packb = (guchar *)g_malloc((4*width * 105)/100+2); - guchar *const plane = (guchar *)g_malloc(4*width); - - os << "image\n"; - - ascii85_init(); - - for (unsigned i = 0; i < height; i++) { - guchar const *const src = px + i * rs; - - guchar const *src_ptr = src; - guchar *plane_ptr = plane; - for (unsigned j = 0; j < width; j++) { - *(plane_ptr++) = *(src_ptr+3); - *(plane_ptr++) = *(src_ptr+0); - *(plane_ptr++) = *(src_ptr+1); - *(plane_ptr++) = *(src_ptr+2); - src_ptr += 4; - } - - ascii85_nout(4*width, plane, os); - } - ascii85_done(os); - - g_free(packb); - g_free(plane); - - os << "grestore\n"; - - fprintf(ofp, "%s", os.str().c_str()); - - return 0; -} - -bool -PrintPS::textToPath(Inkscape::Extension::Print * ext) -{ - return ext->get_param_bool("textToPath"); -} - -/** -* \brief Get "fontEmbedded" param -* \retval TRUE Fonts have to be embedded in the output so that the user might not need to install fonts to have the interpreter read the document correctly -* \retval FALSE No font embedding -* -* Only available for Adobe Type 1 fonts in EPS output till now -*/ -bool -PrintPS::fontEmbedded(Inkscape::Extension::Print * ext) -{ - return ext->get_param_bool("fontEmbedded"); -} - -#include "clear-n_.h" - -void -PrintPS::init(void) -{ - /* SVG in */ - (void) Inkscape::Extension::build_from_mem( - "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" - "<name>" N_("Postscript Print") "</name>\n" - "<id>" SP_MODULE_KEY_PRINT_PS "</id>\n" - "<param name=\"bitmap\" type=\"boolean\">false</param>\n" - "<param name=\"resolution\" type=\"string\">72</param>\n" - "<param name=\"destination\" type=\"string\">| lp</param>\n" - "<param name=\"pageBoundingBox\" type=\"boolean\">true</param>\n" - "<param name=\"textToPath\" type=\"boolean\">true</param>\n" - "<param name=\"fontEmbedded\" type=\"boolean\">false</param>\n" - "<print/>\n" - "</inkscape-extension>", new PrintPS()); -} - - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - -/* End of GNU GPL code */ - - -/* - 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/extension/internal/ps.h b/src/extension/internal/ps.h deleted file mode 100644 index 92928b9e4..000000000 --- a/src/extension/internal/ps.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef EXTENSION_INTERNAL_PS_H_SEEN -#define EXTENSION_INTERNAL_PS_H_SEEN - -/** \file - * Declaration of PrintPS, the internal module used to do Postscript Printing. - */ -/* - * Authors: - * Lauris Kaplinski <lauris@kaplinski.com> - * Ted Gould <ted@gould.cx> - * - * Lauris' original code is in the public domain. - * Ted's changes are licensed under the GNU GPL. - */ - -#include <config.h> -#include "extension/extension.h" -#include "extension/implementation/implementation.h" -#include <set> -#include <string> - -#include <libnrtype/font-instance.h> - -#include "svg/stringstream.h" - -namespace Inkscape { -namespace Extension { -namespace Internal { - -typedef enum {FONT_TYPE1, FONT_TRUETYPE} FontType; - -class PrintPS : public Inkscape::Extension::Implementation::Implementation { - float _width; - float _height; - FILE * _begin_stream;//stream to print prolog and document setup of EPS, if font embedding - FILE * _stream;//(main) stream to print the (E)PS output, or only the script part following prolog/document setup, if font embedding - - unsigned short _dpi; - bool _bitmap; - std::set<std::string> _latin1_encoded_fonts; - bool _newlatin1font_proc_defined; - - GTree * _fonts;//maps fonts used in the document, to (value=)"TRUE" only if the font was effectively embedded, "FALSE" if not. - - //map strings of font types to enumeration of int values - std::map<std::string, FontType> _fontTypesMap; - - void print_2geomcurve(SVGOStringStream &os, Geom::Curve const & c ); - void print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv); - - void print_fill_style(SVGOStringStream &os, SPStyle const *style, NRRect const *pbox); - void print_stroke_style(SVGOStringStream &os, SPStyle const *style); - - char const *PSFontName(SPStyle const *style); - bool embed_t1(SVGOStringStream &os, font_instance* font); - bool embed_font(SVGOStringStream &os, font_instance* font); - - void print_glyphlist(SVGOStringStream &os, font_instance* font, Glib::ustring unistring); - - unsigned int print_image(FILE *ofp, guchar *px, unsigned int width, unsigned int height, unsigned int rs, - Geom::Matrix const *transform); - void compress_packbits(int nin, guchar *src, int *nout, guchar *dst); - - /* ASCII 85 variables */ - guint32 ascii85_buf; - int ascii85_len; - int ascii85_linewidth; - /* ASCII 85 Functions */ - void ascii85_init(void); - void ascii85_flush(SVGOStringStream &os); - inline void ascii85_out(guchar byte, SVGOStringStream &os); - void ascii85_nout(int n, guchar *uptr, SVGOStringStream &os); - void ascii85_done(SVGOStringStream &os); - - -public: - PrintPS(void); - virtual ~PrintPS(void); - - /* Print functions */ - virtual unsigned int setup(Inkscape::Extension::Print *module); - /* - virtual unsigned int set_preview(Inkscape::Extension::Print *module); - */ - - virtual unsigned int begin(Inkscape::Extension::Print *module, SPDocument *doc); - virtual unsigned int finish(Inkscape::Extension::Print *module); - - /* Rendering methods */ - virtual unsigned int bind(Inkscape::Extension::Print *module, Geom::Matrix const *transform, float opacity); - virtual unsigned int release(Inkscape::Extension::Print *module); - virtual unsigned int comment(Inkscape::Extension::Print *module, char const *comment); - virtual unsigned int fill(Inkscape::Extension::Print *module, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); - virtual unsigned int stroke(Inkscape::Extension::Print *module, Geom::PathVector const &pathv, Geom::Matrix const *transform, SPStyle const *style, - NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); - virtual unsigned int image(Inkscape::Extension::Print *module, unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, - Geom::Matrix const *transform, SPStyle const *style); - virtual unsigned int text(Inkscape::Extension::Print *module, char const *text, - Geom::Point p, SPStyle const *style); - - bool textToPath(Inkscape::Extension::Print *ext); - static void init(void); - bool fontEmbedded (Inkscape::Extension::Print * ext); -}; - -} /* namespace Internal */ -} /* namespace Extension */ -} /* namespace Inkscape */ - - -#endif /* !EXTENSION_INTERNAL_PS_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 : diff --git a/src/extension/output.h b/src/extension/output.h index f6f16fb85..b52a96211 100644 --- a/src/extension/output.h +++ b/src/extension/output.h @@ -29,6 +29,7 @@ class Output : public Extension { public: class save_failed {}; /**< Generic failure for an undescribed reason */ + class save_cancelled {}; /**< Saving was cancelled */ class no_extension_found {}; /**< Failed because we couldn't find an extension to match the filename */ Output (Inkscape::XML::Node * in_repr, diff --git a/src/extension/system.cpp b/src/extension/system.cpp index cd70042b6..31cf877a8 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -218,8 +218,9 @@ save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension, throw Output::save_failed(); } - if (!omod->prefs()) - return; + if (!omod->prefs()) { + throw Output::save_cancelled(); + } gchar *fileName = NULL; if (setextension) { diff --git a/src/file.cpp b/src/file.cpp index d5700bb6e..71a3ddd6c 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -589,6 +589,9 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, g_free(text); g_free(safeUri); return FALSE; + } catch (Inkscape::Extension::Output::save_cancelled &e) { + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + return FALSE; } catch (Inkscape::Extension::Output::no_overwrite &e) { return sp_file_save_dialog(parentWindow, doc); } @@ -1003,7 +1006,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, bool const saved_pref = prefs->getBool("/options/transform/pattern", true); prefs->setBool("/options/transform/pattern", true); sp_document_ensure_up_to_date(sp_desktop_document(desktop)); - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); sp_selection_move_relative(selection, m); diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 5bb34415d..1681831c2 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -21,7 +21,7 @@ #include "filter-chemistry.h" #include "filter-enums.h" -#include "sp-feblend.h" +#include "filters/blend.h" #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-gaussian-blur.h" @@ -319,7 +319,7 @@ new_filter_blend_gaussian_blur (SPDocument *document, const char *blendmode, gdo SPFilter * new_filter_simple_from_item (SPDocument *document, SPItem *item, const char *mode, gdouble radius) { - boost::optional<Geom::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); + Geom::OptRect const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); double width; double height; @@ -374,7 +374,7 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item, stdDeviation /= expansion; // Get the object size - boost::optional<Geom::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); + Geom::OptRect const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); double width; double height; if (r) { diff --git a/src/filter-enums.h b/src/filter-enums.h index 87d5c1217..815d439c1 100644 --- a/src/filter-enums.h +++ b/src/filter-enums.h @@ -20,7 +20,7 @@ #include "display/nr-filter-morphology.h" #include "display/nr-filter-turbulence.h" #include "display/nr-filter-types.h" -#include "sp-fedisplacementmap.h" +#include "filters/displacementmap.h" #include "util/enums.h" // Filter primitives diff --git a/src/filters/Makefile_insert b/src/filters/Makefile_insert new file mode 100644 index 000000000..babc72e93 --- /dev/null +++ b/src/filters/Makefile_insert @@ -0,0 +1,64 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +filters/all: filters/libfilters.a + +filters/clean: + rm -f extension/libfilters.a $(extension_libextension_a_OBJECTS) + +filters_libfilters_a_SOURCES = \ + filters/blend.cpp \ + filters/blend-fns.h \ + filters/blend.h \ + filters/colormatrix.cpp \ + filters/colormatrix-fns.h \ + filters/colormatrix.h \ + filters/componenttransfer.cpp \ + filters/componenttransfer-fns.h \ + filters/componenttransfer-funcnode.cpp \ + filters/componenttransfer-funcnode.h \ + filters/componenttransfer.h \ + filters/composite.cpp \ + filters/composite-fns.h \ + filters/composite.h \ + filters/convolvematrix.cpp \ + filters/convolvematrix-fns.h \ + filters/convolvematrix.h \ + filters/diffuselighting.cpp \ + filters/diffuselighting-fns.h \ + filters/diffuselighting.h \ + filters/displacementmap.cpp \ + filters/displacementmap-fns.h \ + filters/displacementmap.h \ + filters/distantlight.cpp \ + filters/distantlight.h \ + filters/flood.cpp \ + filters/flood-fns.h \ + filters/flood.h \ + filters/image.cpp \ + filters/image-fns.h \ + filters/image.h \ + filters/merge.cpp \ + filters/merge-fns.h \ + filters/merge.h \ + filters/mergenode.cpp \ + filters/mergenode.h \ + filters/morphology.cpp \ + filters/morphology-fns.h \ + filters/morphology.h \ + filters/offset.cpp \ + filters/offset-fns.h \ + filters/offset.h \ + filters/pointlight.cpp \ + filters/pointlight.h \ + filters/specularlighting.cpp \ + filters/specularlighting-fns.h \ + filters/specularlighting.h \ + filters/spotlight.cpp \ + filters/spotlight.h \ + filters/tile.cpp \ + filters/tile-fns.h \ + filters/tile.h \ + filters/turbulence.cpp \ + filters/turbulence-fns.h \ + filters/turbulence.h + diff --git a/src/sp-feblend-fns.h b/src/filters/blend-fns.h index f08ed9dd1..f08ed9dd1 100644 --- a/src/sp-feblend-fns.h +++ b/src/filters/blend-fns.h diff --git a/src/sp-feblend.cpp b/src/filters/blend.cpp index 0522a38e3..8c2d7978e 100644 --- a/src/sp-feblend.cpp +++ b/src/filters/blend.cpp @@ -22,7 +22,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-feblend.h" +#include "blend.h" #include "xml/repr.h" #include "display/nr-filter.h" diff --git a/src/sp-feblend.h b/src/filters/blend.h index f6f71b892..bcb95c3c2 100644 --- a/src/sp-feblend.h +++ b/src/filters/blend.h @@ -2,7 +2,7 @@ #define SP_FEBLEND_H_SEEN /** \file - * SVG <feBlend> implementation, see sp-feBlend.cpp. + * SVG <feBlend> implementation, see Blend.cpp. */ /* * Authors: @@ -15,7 +15,7 @@ */ #include "sp-filter.h" -#include "sp-feblend-fns.h" +#include "blend-fns.h" #include "display/nr-filter-blend.h" diff --git a/src/sp-fecolormatrix-fns.h b/src/filters/colormatrix-fns.h index 3a4a8d35c..3a4a8d35c 100644 --- a/src/sp-fecolormatrix-fns.h +++ b/src/filters/colormatrix-fns.h diff --git a/src/sp-fecolormatrix.cpp b/src/filters/colormatrix.cpp index 181b7cd03..29c2458e8 100644 --- a/src/sp-fecolormatrix.cpp +++ b/src/filters/colormatrix.cpp @@ -23,7 +23,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-fecolormatrix.h" +#include "colormatrix.h" #include "xml/repr.h" #include "helper-fns.h" diff --git a/src/sp-fecolormatrix.h b/src/filters/colormatrix.h index e091a0725..4b9eda1a7 100644 --- a/src/sp-fecolormatrix.h +++ b/src/filters/colormatrix.h @@ -2,7 +2,7 @@ #define SP_FECOLORMATRIX_H_SEEN /** \file - * SVG <feColorMatrix> implementation, see sp-feColorMatrix.cpp. + * SVG <feColorMatrix> implementation, see ColorMatrix.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-fecolormatrix-fns.h" +#include "colormatrix-fns.h" #include "display/nr-filter-colormatrix.h" #include <vector> diff --git a/src/sp-fecomponenttransfer-fns.h b/src/filters/componenttransfer-fns.h index 49983770a..49983770a 100644 --- a/src/sp-fecomponenttransfer-fns.h +++ b/src/filters/componenttransfer-fns.h diff --git a/src/sp-fecomponenttransfer-funcnode.cpp b/src/filters/componenttransfer-funcnode.cpp index 91194a31a..72a4e8744 100644 --- a/src/sp-fecomponenttransfer-funcnode.cpp +++ b/src/filters/componenttransfer-funcnode.cpp @@ -22,8 +22,8 @@ #include "attributes.h" #include "document.h" -#include "sp-fecomponenttransfer.h" -#include "sp-fecomponenttransfer-funcnode.h" +#include "componenttransfer.h" +#include "componenttransfer-funcnode.h" #include "display/nr-filter-component-transfer.h" #include "xml/repr.h" #include "helper-fns.h" diff --git a/src/sp-fecomponenttransfer-funcnode.h b/src/filters/componenttransfer-funcnode.h index 2f0b2fc28..2f0b2fc28 100644 --- a/src/sp-fecomponenttransfer-funcnode.h +++ b/src/filters/componenttransfer-funcnode.h diff --git a/src/sp-fecomponenttransfer.cpp b/src/filters/componenttransfer.cpp index e11f5ab3f..09ea48bc6 100644 --- a/src/sp-fecomponenttransfer.cpp +++ b/src/filters/componenttransfer.cpp @@ -22,8 +22,8 @@ #include "document.h" #include "attributes.h" #include "svg/svg.h" -#include "sp-fecomponenttransfer.h" -#include "sp-fecomponenttransfer-funcnode.h" +#include "componenttransfer.h" +#include "componenttransfer-funcnode.h" #include "xml/repr.h" //#include "display/nr-filter-component-transfer.h" diff --git a/src/sp-fecomponenttransfer.h b/src/filters/componenttransfer.h index f32512c7a..515825d65 100644 --- a/src/sp-fecomponenttransfer.h +++ b/src/filters/componenttransfer.h @@ -2,7 +2,7 @@ #define SP_FECOMPONENTTRANSFER_H_SEEN /** \file - * SVG <feComponentTransfer> implementation, see sp-feComponentTransfer.cpp. + * SVG <feComponentTransfer> implementation, see ComponentTransfer.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-fecomponenttransfer-fns.h" +#include "componenttransfer-fns.h" #include "display/nr-filter-component-transfer.h" #include <vector> diff --git a/src/sp-fecomposite-fns.h b/src/filters/composite-fns.h index c79cb17bb..c79cb17bb 100644 --- a/src/sp-fecomposite-fns.h +++ b/src/filters/composite-fns.h diff --git a/src/sp-fecomposite.cpp b/src/filters/composite.cpp index 11d101bd6..61658ba9e 100644 --- a/src/sp-fecomposite.cpp +++ b/src/filters/composite.cpp @@ -19,7 +19,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-fecomposite.h" +#include "composite.h" #include "helper-fns.h" #include "xml/repr.h" #include "display/nr-filter-composite.h" diff --git a/src/sp-fecomposite.h b/src/filters/composite.h index 280eae145..095d7616d 100644 --- a/src/sp-fecomposite.h +++ b/src/filters/composite.h @@ -2,7 +2,7 @@ #define SP_FECOMPOSITE_H_SEEN /** \file - * SVG <feComposite> implementation, see sp-feComposite.cpp. + * SVG <feComposite> implementation, see Composite.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-fecomposite-fns.h" +#include "composite-fns.h" enum FeCompositeOperator { // Default value is 'over', but let's distinquish specifying the diff --git a/src/sp-feconvolvematrix-fns.h b/src/filters/convolvematrix-fns.h index 76baf7f41..76baf7f41 100644 --- a/src/sp-feconvolvematrix-fns.h +++ b/src/filters/convolvematrix-fns.h diff --git a/src/sp-feconvolvematrix.cpp b/src/filters/convolvematrix.cpp index 816c793e1..a930bc4e7 100644 --- a/src/sp-feconvolvematrix.cpp +++ b/src/filters/convolvematrix.cpp @@ -23,7 +23,7 @@ #include <vector> #include "attributes.h" #include "svg/svg.h" -#include "sp-feconvolvematrix.h" +#include "convolvematrix.h" #include "helper-fns.h" #include "xml/repr.h" #include "display/nr-filter-convolve-matrix.h" diff --git a/src/sp-feconvolvematrix.h b/src/filters/convolvematrix.h index 2cdeee2e8..991f63988 100644 --- a/src/sp-feconvolvematrix.h +++ b/src/filters/convolvematrix.h @@ -2,7 +2,7 @@ #define SP_FECONVOLVEMATRIX_H_SEEN /** \file - * SVG <feConvolveMatrix> implementation, see sp-feConvolveMatrix.cpp. + * SVG <feConvolveMatrix> implementation, see ConvolveMatrix.cpp. */ /* * Authors: @@ -15,7 +15,7 @@ */ #include "sp-filter.h" -#include "sp-feconvolvematrix-fns.h" +#include "convolvematrix-fns.h" #include "number-opt-number.h" #include "display/nr-filter-convolve-matrix.h" #include <vector> diff --git a/src/sp-fediffuselighting-fns.h b/src/filters/diffuselighting-fns.h index b91ed80f6..b91ed80f6 100644 --- a/src/sp-fediffuselighting-fns.h +++ b/src/filters/diffuselighting-fns.h diff --git a/src/sp-fediffuselighting.cpp b/src/filters/diffuselighting.cpp index 96dee569b..a4935bf72 100644 --- a/src/sp-fediffuselighting.cpp +++ b/src/filters/diffuselighting.cpp @@ -23,7 +23,7 @@ #include "svg/svg.h" #include "sp-object.h" #include "svg/svg-color.h" -#include "sp-fediffuselighting.h" +#include "diffuselighting.h" #include "xml/repr.h" #include "display/nr-filter-diffuselighting.h" diff --git a/src/sp-fediffuselighting.h b/src/filters/diffuselighting.h index 7d5bca8a3..8e909f9ae 100644 --- a/src/sp-fediffuselighting.h +++ b/src/filters/diffuselighting.h @@ -2,7 +2,7 @@ #define SP_FEDIFFUSELIGHTING_H_SEEN /** \file - * SVG <feDiffuseLighting> implementation, see sp-feDiffuseLighting.cpp. + * SVG <feDiffuseLighting> implementation, see DiffuseLighting.cpp. */ /* * Authors: @@ -16,7 +16,7 @@ */ #include "sp-filter.h" -#include "sp-fediffuselighting-fns.h" +#include "diffuselighting-fns.h" namespace NR { class FilterDiffuseLighting; diff --git a/src/sp-fedisplacementmap-fns.h b/src/filters/displacementmap-fns.h index 6d92c6b78..6d92c6b78 100644 --- a/src/sp-fedisplacementmap-fns.h +++ b/src/filters/displacementmap-fns.h diff --git a/src/sp-fedisplacementmap.cpp b/src/filters/displacementmap.cpp index a30dd2f9b..405922b46 100644 --- a/src/sp-fedisplacementmap.cpp +++ b/src/filters/displacementmap.cpp @@ -19,7 +19,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-fedisplacementmap.h" +#include "displacementmap.h" #include "xml/repr.h" #include "display/nr-filter-displacement-map.h" #include "helper-fns.h" diff --git a/src/sp-fedisplacementmap.h b/src/filters/displacementmap.h index 914f770b5..6a8ac9cd9 100644 --- a/src/sp-fedisplacementmap.h +++ b/src/filters/displacementmap.h @@ -2,7 +2,7 @@ #define SP_FEDISPLACEMENTMAP_H_SEEN /** \file - * SVG <feDisplacementMap> implementation, see sp-feDisplacementMap.cpp. + * SVG <feDisplacementMap> implementation, see DisplacementMap.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-fedisplacementmap-fns.h" +#include "displacementmap-fns.h" enum FilterDisplacementMapChannelSelector { DISPLACEMENTMAP_CHANNEL_RED, diff --git a/src/sp-fedistantlight.cpp b/src/filters/distantlight.cpp index 3ac3a5016..41584c4a4 100644 --- a/src/sp-fedistantlight.cpp +++ b/src/filters/distantlight.cpp @@ -22,9 +22,9 @@ #include "attributes.h" #include "document.h" -#include "sp-fedistantlight.h" -#include "sp-fediffuselighting-fns.h" -#include "sp-fespecularlighting-fns.h" +#include "distantlight.h" +#include "diffuselighting-fns.h" +#include "specularlighting-fns.h" #include "xml/repr.h" #define SP_MACROS_SILENT diff --git a/src/sp-fedistantlight.h b/src/filters/distantlight.h index 21edbc56c..21edbc56c 100644 --- a/src/sp-fedistantlight.h +++ b/src/filters/distantlight.h diff --git a/src/sp-feflood-fns.h b/src/filters/flood-fns.h index 8cc507274..8cc507274 100644 --- a/src/sp-feflood-fns.h +++ b/src/filters/flood-fns.h diff --git a/src/sp-feflood.cpp b/src/filters/flood.cpp index 14488b7fb..31aa9559a 100644 --- a/src/sp-feflood.cpp +++ b/src/filters/flood.cpp @@ -19,7 +19,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-feflood.h" +#include "flood.h" #include "xml/repr.h" #include "helper-fns.h" #include "svg/svg-color.h" diff --git a/src/sp-feflood.h b/src/filters/flood.h index 4d1702258..046c0e868 100644 --- a/src/sp-feflood.h +++ b/src/filters/flood.h @@ -2,7 +2,7 @@ #define SP_FEFLOOD_H_SEEN /** \file - * SVG <feFlood> implementation, see sp-feFlood.cpp. + * SVG <feFlood> implementation, see Flood.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-feflood-fns.h" +#include "flood-fns.h" #include "display/nr-filter.h" #include "display/nr-filter-flood.h" diff --git a/src/sp-feimage-fns.h b/src/filters/image-fns.h index 0a8b453fe..0a8b453fe 100644 --- a/src/sp-feimage-fns.h +++ b/src/filters/image-fns.h diff --git a/src/sp-feimage.cpp b/src/filters/image.cpp index 117e9ffca..d132d361c 100644 --- a/src/sp-feimage.cpp +++ b/src/filters/image.cpp @@ -22,7 +22,7 @@ #include "uri-references.h" #include "attributes.h" #include "svg/svg.h" -#include "sp-feimage.h" +#include "image.h" #include "xml/repr.h" #include <string.h> diff --git a/src/sp-feimage.h b/src/filters/image.h index dc432a672..8952aee6c 100644 --- a/src/sp-feimage.h +++ b/src/filters/image.h @@ -2,7 +2,7 @@ #define SP_FEIMAGE_H_SEEN /** \file - * SVG <feImage> implementation, see sp-feImage.cpp. + * SVG <feImage> implementation, see Image.cpp. */ /* * Authors: @@ -15,7 +15,7 @@ */ #include "sp-filter.h" -#include "sp-feimage-fns.h" +#include "image-fns.h" #include "svg/svg-length.h" #include "sp-item.h" #include "uri-references.h" diff --git a/src/filters/makefile.in b/src/filters/makefile.in new file mode 100644 index 000000000..5aa76ce1b --- /dev/null +++ b/src/filters/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +OBJEXT = @OBJEXT@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) filters/all + +clean %.a %.$(OBJEXT): + cd .. && $(MAKE) filters/$@ + +.PHONY: all clean + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/sp-femerge-fns.h b/src/filters/merge-fns.h index 24bda1ae2..24bda1ae2 100644 --- a/src/sp-femerge-fns.h +++ b/src/filters/merge-fns.h diff --git a/src/sp-femerge.cpp b/src/filters/merge.cpp index 9e45d44ab..079d1b19c 100644 --- a/src/sp-femerge.cpp +++ b/src/filters/merge.cpp @@ -21,8 +21,8 @@ #include "svg/svg.h" #include "xml/repr.h" -#include "sp-femerge.h" -#include "sp-femergenode.h" +#include "merge.h" +#include "mergenode.h" #include "display/nr-filter-merge.h" /* FeMerge base class */ diff --git a/src/sp-femerge.h b/src/filters/merge.h index f83697fca..5d28faba9 100644 --- a/src/sp-femerge.h +++ b/src/filters/merge.h @@ -2,7 +2,7 @@ #define SP_FEMERGE_H_SEEN /** \file - * SVG <feMerge> implementation, see sp-feMerge.cpp. + * SVG <feMerge> implementation, see Merge.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-femerge-fns.h" +#include "merge-fns.h" /* FeMerge base class */ class SPFeMergeClass; diff --git a/src/sp-femergenode.cpp b/src/filters/mergenode.cpp index 153a61988..1f056a25f 100644 --- a/src/sp-femergenode.cpp +++ b/src/filters/mergenode.cpp @@ -20,8 +20,8 @@ #include "attributes.h" #include "xml/repr.h" -#include "sp-femergenode.h" -#include "sp-femerge.h" +#include "mergenode.h" +#include "merge.h" static void sp_feMergeNode_class_init(SPFeMergeNodeClass *klass); static void sp_feMergeNode_init(SPFeMergeNode *skeleton); diff --git a/src/sp-femergenode.h b/src/filters/mergenode.h index 8ec00bdcd..8ec00bdcd 100644 --- a/src/sp-femergenode.h +++ b/src/filters/mergenode.h diff --git a/src/sp-femorphology-fns.h b/src/filters/morphology-fns.h index a0550405d..a0550405d 100644 --- a/src/sp-femorphology-fns.h +++ b/src/filters/morphology-fns.h diff --git a/src/sp-femorphology.cpp b/src/filters/morphology.cpp index 01290391f..927616091 100644 --- a/src/sp-femorphology.cpp +++ b/src/filters/morphology.cpp @@ -22,7 +22,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-femorphology.h" +#include "morphology.h" #include "xml/repr.h" #include "display/nr-filter-morphology.h" diff --git a/src/sp-femorphology.h b/src/filters/morphology.h index 1229c90d1..8e807d73a 100644 --- a/src/sp-femorphology.h +++ b/src/filters/morphology.h @@ -2,7 +2,7 @@ #define SP_FEMORPHOLOGY_H_SEEN /** \file - * SVG <feMorphology> implementation, see sp-feMorphology.cpp. + * SVG <feMorphology> implementation, see Morphology.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-femorphology-fns.h" +#include "morphology-fns.h" #include "number-opt-number.h" #include "display/nr-filter.h" #include "display/nr-filter-morphology.h" diff --git a/src/sp-feoffset-fns.h b/src/filters/offset-fns.h index 38561c188..38561c188 100644 --- a/src/sp-feoffset-fns.h +++ b/src/filters/offset-fns.h diff --git a/src/sp-feoffset.cpp b/src/filters/offset.cpp index 228424c70..084863612 100644 --- a/src/sp-feoffset.cpp +++ b/src/filters/offset.cpp @@ -20,7 +20,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-feoffset.h" +#include "offset.h" #include "helper-fns.h" #include "xml/repr.h" #include "display/nr-filter-offset.h" diff --git a/src/sp-feoffset.h b/src/filters/offset.h index 042711495..72d852514 100644 --- a/src/sp-feoffset.h +++ b/src/filters/offset.h @@ -2,7 +2,7 @@ #define SP_FEOFFSET_H_SEEN /** \file - * SVG <feOffset> implementation, see sp-feOffset.cpp. + * SVG <feOffset> implementation, see Offset.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-feoffset-fns.h" +#include "offset-fns.h" /* FeOffset base class */ class SPFeOffsetClass; diff --git a/src/sp-fepointlight.cpp b/src/filters/pointlight.cpp index 5317b96fc..ce58cf13e 100644 --- a/src/sp-fepointlight.cpp +++ b/src/filters/pointlight.cpp @@ -22,9 +22,9 @@ #include "attributes.h" #include "document.h" -#include "sp-fepointlight.h" -#include "sp-fediffuselighting-fns.h" -#include "sp-fespecularlighting-fns.h" +#include "pointlight.h" +#include "diffuselighting-fns.h" +#include "specularlighting-fns.h" #include "xml/repr.h" #define SP_MACROS_SILENT diff --git a/src/sp-fepointlight.h b/src/filters/pointlight.h index 915d726af..915d726af 100644 --- a/src/sp-fepointlight.h +++ b/src/filters/pointlight.h diff --git a/src/sp-fespecularlighting-fns.h b/src/filters/specularlighting-fns.h index bd48ba684..bd48ba684 100644 --- a/src/sp-fespecularlighting-fns.h +++ b/src/filters/specularlighting-fns.h diff --git a/src/sp-fespecularlighting.cpp b/src/filters/specularlighting.cpp index c4e2902d6..baf9bb7c2 100644 --- a/src/sp-fespecularlighting.cpp +++ b/src/filters/specularlighting.cpp @@ -23,7 +23,7 @@ #include "svg/svg.h" #include "sp-object.h" #include "svg/svg-color.h" -#include "sp-fespecularlighting.h" +#include "specularlighting.h" #include "xml/repr.h" #include "display/nr-filter-specularlighting.h" diff --git a/src/sp-fespecularlighting.h b/src/filters/specularlighting.h index 5d2194c2f..c2a55df51 100644 --- a/src/sp-fespecularlighting.h +++ b/src/filters/specularlighting.h @@ -2,7 +2,7 @@ #define SP_FESPECULARLIGHTING_H_SEEN /** \file - * SVG <feSpecularLighting> implementation, see sp-feSpecularLighting.cpp. + * SVG <feSpecularLighting> implementation, see SpecularLighting.cpp. */ /* * Authors: @@ -16,7 +16,7 @@ */ #include "sp-filter.h" -#include "sp-fespecularlighting-fns.h" +#include "specularlighting-fns.h" namespace NR { class FilterSpecularLighting; diff --git a/src/sp-fespotlight.cpp b/src/filters/spotlight.cpp index b66912468..3b518f0b4 100644 --- a/src/sp-fespotlight.cpp +++ b/src/filters/spotlight.cpp @@ -22,9 +22,9 @@ #include "attributes.h" #include "document.h" -#include "sp-fespotlight.h" -#include "sp-fediffuselighting-fns.h" -#include "sp-fespecularlighting-fns.h" +#include "spotlight.h" +#include "diffuselighting-fns.h" +#include "specularlighting-fns.h" #include "xml/repr.h" #define SP_MACROS_SILENT diff --git a/src/sp-fespotlight.h b/src/filters/spotlight.h index d48cf6daa..d48cf6daa 100644 --- a/src/sp-fespotlight.h +++ b/src/filters/spotlight.h diff --git a/src/sp-fetile-fns.h b/src/filters/tile-fns.h index b7c4c5f27..b7c4c5f27 100644 --- a/src/sp-fetile-fns.h +++ b/src/filters/tile-fns.h diff --git a/src/sp-fetile.cpp b/src/filters/tile.cpp index 598ccdb84..ab4f9a27a 100644 --- a/src/sp-fetile.cpp +++ b/src/filters/tile.cpp @@ -19,7 +19,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-fetile.h" +#include "tile.h" #include "xml/repr.h" diff --git a/src/sp-fetile.h b/src/filters/tile.h index efcccf11d..9e12ca7ee 100644 --- a/src/sp-fetile.h +++ b/src/filters/tile.h @@ -2,7 +2,7 @@ #define SP_FETILE_H_SEEN /** \file - * SVG <feTile> implementation, see sp-feTile.cpp. + * SVG <feTile> implementation, see Tile.cpp. */ /* * Authors: @@ -14,7 +14,7 @@ */ #include "sp-filter.h" -#include "sp-fetile-fns.h" +#include "tile-fns.h" #include "display/nr-filter.h" #include "display/nr-filter-tile.h" diff --git a/src/sp-feturbulence-fns.h b/src/filters/turbulence-fns.h index 43b4450a5..43b4450a5 100644 --- a/src/sp-feturbulence-fns.h +++ b/src/filters/turbulence-fns.h diff --git a/src/sp-feturbulence.cpp b/src/filters/turbulence.cpp index fcaf6c56f..1d7a1c840 100644 --- a/src/sp-feturbulence.cpp +++ b/src/filters/turbulence.cpp @@ -21,7 +21,7 @@ #include "attributes.h" #include "svg/svg.h" -#include "sp-feturbulence.h" +#include "turbulence.h" #include "helper-fns.h" #include "xml/repr.h" #include <string.h> diff --git a/src/sp-feturbulence.h b/src/filters/turbulence.h index 6ae993d27..3601a7cdc 100644 --- a/src/sp-feturbulence.h +++ b/src/filters/turbulence.h @@ -2,7 +2,7 @@ #define SP_FETURBULENCE_H_SEEN /** \file - * SVG <feTurbulence> implementation, see sp-feTurbulence.cpp. + * SVG <feTurbulence> implementation, see Turbulence.cpp. */ /* * Authors: @@ -15,7 +15,7 @@ */ #include "sp-filter.h" -#include "sp-feturbulence-fns.h" +#include "turbulence-fns.h" #include "number-opt-number.h" #include "display/nr-filter-turbulence.h" diff --git a/src/flood-context.cpp b/src/flood-context.cpp index 992791976..a45ec5dfe 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -807,7 +807,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even sp_document_ensure_up_to_date (document); SPItem *document_root = SP_ITEM(SP_DOCUMENT_ROOT(document)); - boost::optional<Geom::Rect> bbox = document_root->getBounds(Geom::identity()); + Geom::OptRect bbox = document_root->getBounds(Geom::identity()); if (!bbox) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Area is not bounded</b>, cannot fill.")); diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 0fa24ccad..4abd7483f 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -285,9 +285,9 @@ sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item) // calculate the bbox of the item sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); - boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine + Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine - if ( !bbox || bbox->isEmpty() ) + if (!bbox) return gr; Geom::Coord const width = bbox->dimensions()[Geom::X]; @@ -346,8 +346,8 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop // calculate the bbox of the item sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); Geom::Matrix bbox2user; - boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine - if ( bbox && !bbox->isEmpty() ) { + Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine + if ( bbox ) { bbox2user = Geom::Matrix(bbox->dimensions()[Geom::X], 0, 0, bbox->dimensions()[Geom::Y], bbox->min()[Geom::X], bbox->min()[Geom::Y]); @@ -1098,7 +1098,7 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool if (SP_GRADIENT(gradient)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); - boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine + Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine if (bbox) { p *= Geom::Matrix(bbox->dimensions()[Geom::X], 0, 0, bbox->dimensions()[Geom::Y], diff --git a/src/gradient-context.cpp b/src/gradient-context.cpp index 3741bc499..b4f52a7c9 100644 --- a/src/gradient-context.cpp +++ b/src/gradient-context.cpp @@ -57,7 +57,7 @@ static void sp_gradient_context_setup(SPEventContext *ec); static gint sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event); -static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint state, guint32 etime); +static void sp_gradient_drag(SPGradientContext &rc, Geom::Point const pt, guint state, guint32 etime); static SPEventContextClass *parent_class; @@ -241,7 +241,7 @@ sp_gradient_context_select_prev (SPEventContext *event_context) } static bool -sp_gradient_context_is_over_line (SPGradientContext *rc, SPItem *item, NR::Point event_p) +sp_gradient_context_is_over_line (SPGradientContext *rc, SPItem *item, Geom::Point event_p) { SPDesktop *desktop = SP_EVENT_CONTEXT (rc)->desktop; @@ -260,10 +260,10 @@ sp_gradient_context_is_over_line (SPGradientContext *rc, SPItem *item, NR::Point return close; } -std::vector<NR::Point> +std::vector<Geom::Point> sp_gradient_context_get_stop_intervals (GrDrag *drag, GSList **these_stops, GSList **next_stops) { - std::vector<NR::Point> coords; + std::vector<Geom::Point> coords; // for all selected draggers for (GList *i = drag->selected; i != NULL; i = i->next) { @@ -349,7 +349,7 @@ sp_gradient_context_add_stops_between_selected_stops (SPGradientContext *rc) GSList *these_stops = NULL; GSList *next_stops = NULL; - std::vector<NR::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); + std::vector<Geom::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); if (g_slist_length(these_stops) == 0 && drag->numSelected() == 1) { // if a single stop is selected, add between that stop and the next one @@ -406,7 +406,7 @@ sp_gradient_simplify(SPGradientContext *rc, double tolerance) GSList *these_stops = NULL; GSList *next_stops = NULL; - std::vector<NR::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); + std::vector<Geom::Point> coords = sp_gradient_context_get_stop_intervals (drag, &these_stops, &next_stops); GSList *todel = NULL; @@ -464,7 +464,7 @@ sp_gradient_simplify(SPGradientContext *rc, double tolerance) static void -sp_gradient_context_add_stop_near_point (SPGradientContext *rc, SPItem *item, NR::Point mouse_p, guint32 /*etime*/) +sp_gradient_context_add_stop_near_point (SPGradientContext *rc, SPItem *item, Geom::Point mouse_p, guint32 /*etime*/) { // item is the selected item. mouse_p the location in doc coordinates of where to add the stop @@ -508,7 +508,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) if (drag->lines) { for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { line = (SPCtrlLine*) l->data; - over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y)); + over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); } } if (over_line) { @@ -535,11 +535,11 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) break; case GDK_BUTTON_PRESS: if ( event->button.button == 1 && !event_context->space_panning ) { - NR::Point button_w(event->button.x, event->button.y); + Geom::Point button_w(event->button.x, event->button.y); // save drag origin - event_context->xp = (gint) button_w[NR::X]; - event_context->yp = (gint) button_w[NR::Y]; + event_context->xp = (gint) button_w[Geom::X]; + event_context->yp = (gint) button_w[Geom::Y]; event_context->within_tolerance = true; dragging = true; @@ -577,9 +577,9 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) // motion notify coordinates as given (no snapping back to origin) event_context->within_tolerance = false; - NR::Point const motion_w(event->motion.x, + Geom::Point const motion_w(event->motion.x, event->motion.y); - NR::Point const motion_dt = event_context->desktop->w2d(motion_w); + Geom::Point const motion_dt = event_context->desktop->w2d(motion_w); if (Inkscape::Rubberband::get(desktop)->is_started()) { Inkscape::Rubberband::get(desktop)->move(motion_dt); @@ -594,7 +594,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) bool over_line = false; if (drag->lines) { for (GSList *l = drag->lines; l != NULL; l = l->next) { - over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) l->data, NR::Point(event->motion.x, event->motion.y)); + over_line |= sp_gradient_context_is_over_line (rc, (SPItem*) l->data, Geom::Point(event->motion.x, event->motion.y)); } } @@ -618,7 +618,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) if (drag->lines) { for (GSList *l = drag->lines; (l != NULL) && (!over_line); l = l->next) { line = (SPCtrlLine*) l->data; - over_line = sp_gradient_context_is_over_line (rc, (SPItem*) line, NR::Point(event->motion.x, event->motion.y)); + over_line = sp_gradient_context_is_over_line (rc, (SPItem*) line, Geom::Point(event->motion.x, event->motion.y)); if (over_line) break; } @@ -643,7 +643,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) if (r->is_started() && !event_context->within_tolerance) { // this was a rubberband drag if (r->getMode() == RUBBERBAND_MODE_RECT) { - boost::optional<Geom::Rect> const b = r->getRectangle(); + Geom::OptRect const b = r->getRectangle(); drag->selectRect(*b); } } @@ -855,7 +855,7 @@ sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) return ret; } -static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint /*state*/, guint32 etime) +static void sp_gradient_drag(SPGradientContext &rc, Geom::Point const pt, guint /*state*/, guint32 etime) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; Inkscape::Selection *selection = sp_desktop_selection(desktop); diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index b507ab72b..1394cd758 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -283,7 +283,7 @@ guint32 GrDrag::getColor() } SPStop * -GrDrag::addStopNearPoint (SPItem *item, NR::Point mouse_p, double tolerance) +GrDrag::addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance) { gfloat offset; // type of SPStop.offset = gfloat SPGradient *gradient; @@ -294,10 +294,10 @@ GrDrag::addStopNearPoint (SPItem *item, NR::Point mouse_p, double tolerance) do { gradient = sp_item_gradient (item, fill_or_stroke); if (SP_IS_LINEARGRADIENT(gradient)) { - NR::Point begin = sp_item_gradient_get_coords(item, POINT_LG_BEGIN, 0, fill_or_stroke); - NR::Point end = sp_item_gradient_get_coords(item, POINT_LG_END, 0, fill_or_stroke); + Geom::Point begin = sp_item_gradient_get_coords(item, POINT_LG_BEGIN, 0, fill_or_stroke); + Geom::Point end = sp_item_gradient_get_coords(item, POINT_LG_END, 0, fill_or_stroke); - NR::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0); + Geom::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0); double dist_screen = NR::L2 (mouse_p - nearest); if ( dist_screen < tolerance ) { // add the knot @@ -306,9 +306,9 @@ GrDrag::addStopNearPoint (SPItem *item, NR::Point mouse_p, double tolerance) break; // break out of the while loop: add only one knot } } else if (SP_IS_RADIALGRADIENT(gradient)) { - NR::Point begin = sp_item_gradient_get_coords(item, POINT_RG_CENTER, 0, fill_or_stroke); - NR::Point end = sp_item_gradient_get_coords(item, POINT_RG_R1, 0, fill_or_stroke); - NR::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0); + Geom::Point begin = sp_item_gradient_get_coords(item, POINT_RG_CENTER, 0, fill_or_stroke); + Geom::Point end = sp_item_gradient_get_coords(item, POINT_RG_R1, 0, fill_or_stroke); + Geom::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0); double dist_screen = NR::L2 (mouse_p - nearest); if ( dist_screen < tolerance ) { offset = get_offset_between_points(nearest, begin, end); @@ -358,7 +358,7 @@ GrDrag::addStopNearPoint (SPItem *item, NR::Point mouse_p, double tolerance) bool -GrDrag::dropColor(SPItem */*item*/, gchar *c, NR::Point p) +GrDrag::dropColor(SPItem */*item*/, gchar *c, Geom::Point p) { // first, see if we can drop onto one of the existing draggers for (GList *i = draggers; i != NULL; i = i->next) { // for all draggables of dragger @@ -384,7 +384,7 @@ GrDrag::dropColor(SPItem */*item*/, gchar *c, NR::Point p) if (lines) { for (GSList *l = lines; (l != NULL) && (!over_line); l = l->next) { line = (SPCtrlLine*) l->data; - NR::Point nearest = snap_vector_midpoint (p, line->s, line->e, 0); + Geom::Point nearest = snap_vector_midpoint (p, line->s, line->e, 0); double dist_screen = NR::L2 (p - nearest) * desktop->current_zoom(); if (line->item && dist_screen < 5) { SPStop *stop = addStopNearPoint (line->item, p, 5/desktop->current_zoom()); @@ -517,13 +517,29 @@ GrDraggable::getServer () return server; } +static +boost::optional<Geom::Point> +get_snap_vector (Geom::Point p, Geom::Point o, double snap, double initial) +{ + double r = L2 (p - o); + if (r < 1e-3) { + return boost::optional<Geom::Point>(); + } + + double angle = atan2 (p - o); + // snap angle to snaps increments, starting from initial: + double a_snapped = initial + floor((angle - initial)/snap + 0.5) * snap; + // calculate the new position and subtract p to get the vector: + return (o + r * Geom::Point(cos(a_snapped), sin(a_snapped)) - p); +} + static void -gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpointer data) +gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gpointer data) { GrDragger *dragger = (GrDragger *) data; GrDrag *drag = dragger->parent; - NR::Point p = *ppointer; + Geom::Point p = ppointer; // FIXME: take from prefs double snap_dist = SNAP_DIST / dragger->parent->desktop->current_zoom(); @@ -591,18 +607,18 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi double dist = NR_HUGE; // No snapping so far, let's see if we need to snap to any of the levels for (guint i = 0; i < dragger->parent->hor_levels.size(); i++) { - dist = fabs(p[NR::Y] - dragger->parent->hor_levels[i]); + dist = fabs(p[Geom::Y] - dragger->parent->hor_levels[i]); if (dist < snap_dist) { - p[NR::Y] = dragger->parent->hor_levels[i]; + p[Geom::Y] = dragger->parent->hor_levels[i]; s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false); was_snapped = true; sp_knot_moveto (knot, p); } } for (guint i = 0; i < dragger->parent->vert_levels.size(); i++) { - dist = fabs(p[NR::X] - dragger->parent->vert_levels[i]); + dist = fabs(p[Geom::X] - dragger->parent->vert_levels[i]); if (dist < snap_dist) { - p[NR::X] = dragger->parent->vert_levels[i]; + p[Geom::X] = dragger->parent->vert_levels[i]; s = Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_GRADIENT, dist, snap_dist, false, false); was_snapped = true; sp_knot_moveto (knot, p); @@ -625,7 +641,7 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { GrDraggable *draggable = (GrDraggable *) i->data; - NR::Point *dr_snap = NULL; + Geom::Point dr_snap(Geom::infinity(), Geom::infinity()); if (draggable->point_type == POINT_LG_BEGIN || draggable->point_type == POINT_LG_END) { for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { @@ -638,11 +654,11 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi // found the other end of the linear gradient; if (state & GDK_SHIFT_MASK) { // moving linear around center - NR::Point center = NR::Point (0.5*(d_new->point + dragger->point)); - dr_snap = ¢er; + Geom::Point center = Geom::Point (0.5*(d_new->point + dragger->point)); + dr_snap = center; } else { // moving linear around the other end - dr_snap = &d_new->point; + dr_snap = d_new->point; } } } @@ -655,37 +671,37 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi POINT_RG_CENTER, draggable->fill_or_stroke)) { // found the center of the radial gradient; - dr_snap = &(d_new->point); + dr_snap = d_new->point; } } } else if (draggable->point_type == POINT_RG_CENTER) { // radial center snaps to hor/vert relative to its original position - dr_snap = &(dragger->point_original); + dr_snap = dragger->point_original; } - NR::Point *snap_vector = NULL; - if (dr_snap) { + boost::optional<Geom::Point> snap_vector; + if (dr_snap.isFinite()) { if (state & GDK_MOD1_MASK) { // with Alt, snap to the original angle and its perpendiculars - snap_vector = get_snap_vector (p, *dr_snap, M_PI/2, NR::atan2 (dragger->point_original - *dr_snap)); + snap_vector = get_snap_vector (p, dr_snap, M_PI/2, NR::atan2 (dragger->point_original - dr_snap)); } else { // with Ctrl, snap to M_PI/snaps - snap_vector = get_snap_vector (p, *dr_snap, M_PI/snaps, 0); + snap_vector = get_snap_vector (p, dr_snap, M_PI/snaps, 0); } } if (snap_vector) { - snap_vectors = g_slist_prepend (snap_vectors, snap_vector); + snap_vectors = g_slist_prepend (snap_vectors, &(*snap_vector)); } } // Move by the smallest of snap vectors: - NR::Point move(9999, 9999); + Geom::Point move(9999, 9999); for (GSList const *i = snap_vectors; i != NULL; i = i->next) { - NR::Point *snap_vector = (NR::Point *) i->data; + Geom::Point *snap_vector = (Geom::Point *) i->data; if (NR::L2(*snap_vector) < NR::L2(move)) move = *snap_vector; } - if (move[NR::X] < 9999) { + if (move[Geom::X] < 9999) { p += move; sp_knot_moveto (knot, p); } @@ -697,8 +713,8 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi bool scale_radial = (state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK); if (drag->keep_selection) { - NR::Point diff = p - dragger->point; - drag->selected_move_nowrite (diff[NR::X], diff[NR::Y], scale_radial); + Geom::Point diff = p - dragger->point; + drag->selected_move_nowrite (diff[Geom::X], diff[Geom::Y], scale_radial); } else { dragger->point = p; dragger->fireDraggables (false, scale_radial); @@ -709,7 +725,7 @@ gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpoi static void -gr_midpoint_limits(GrDragger *dragger, SPObject *server, NR::Point *begin, NR::Point *end, NR::Point *low_lim, NR::Point *high_lim, GSList **moving) +gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point *begin, Geom::Point *end, Geom::Point *low_lim, Geom::Point *high_lim, GSList **moving) { GrDrag *drag = dragger->parent; @@ -797,7 +813,7 @@ gr_midpoint_limits(GrDragger *dragger, SPObject *server, NR::Point *begin, NR::P Called when a midpoint knot is dragged. */ static void -gr_knot_moved_midpoint_handler(SPKnot */*knot*/, NR::Point const *ppointer, guint state, gpointer data) +gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state, gpointer data) { GrDragger *dragger = (GrDragger *) data; GrDrag *drag = dragger->parent; @@ -807,9 +823,9 @@ gr_knot_moved_midpoint_handler(SPKnot */*knot*/, NR::Point const *ppointer, guin // FIXME: take from prefs double snap_fraction = 0.1; - NR::Point p = *ppointer; - NR::Point begin(0,0), end(0,0); - NR::Point low_lim(0,0), high_lim(0,0); + Geom::Point p = ppointer; + Geom::Point begin(0,0), end(0,0); + Geom::Point low_lim(0,0), high_lim(0,0); SPObject *server = draggable->getServer(); @@ -821,12 +837,12 @@ gr_knot_moved_midpoint_handler(SPKnot */*knot*/, NR::Point const *ppointer, guin } else { p = snap_vector_midpoint (p, low_lim, high_lim, 0); } - NR::Point displacement = p - dragger->point; + Geom::Point displacement = p - dragger->point; for (GSList const* i = moving; i != NULL; i = i->next) { GrDragger *drg = (GrDragger*) i->data; SPKnot *drgknot = drg->knot; - NR::Point this_move = displacement; + Geom::Point this_move = displacement; if (state & GDK_MOD1_MASK) { // FIXME: unify all these profiles (here, in nodepath, in tweak) in one place double alpha = 1.0; @@ -1271,15 +1287,14 @@ GrDragger::updateDependencies (bool write_repr) -GrDragger::GrDragger (GrDrag *parent, NR::Point p, GrDraggable *draggable) +GrDragger::GrDragger (GrDrag *parent, Geom::Point p, GrDraggable *draggable) + : point(p), + point_original(p) { this->draggables = NULL; this->parent = parent; - this->point = p; - this->point_original = p; - // create the knot this->knot = sp_knot_new (parent->desktop, NULL); this->knot->setMode(SP_KNOT_MODE_XOR); @@ -1432,7 +1447,7 @@ GrDrag::selectAll() \brief Select all stops/draggers that match the coords */ void -GrDrag::selectByCoords(std::vector<NR::Point> coords) +GrDrag::selectByCoords(std::vector<Geom::Point> coords) { for (GList *l = this->draggers; l != NULL; l = l->next) { GrDragger *d = ((GrDragger *) l->data); @@ -1524,7 +1539,7 @@ GrDrag::setDeselected (GrDragger *dragger) Create a line from p1 to p2 and add it to the lines list */ void -GrDrag::addLine (SPItem *item, NR::Point p1, NR::Point p2, guint32 rgba) +GrDrag::addLine (SPItem *item, Geom::Point p1, Geom::Point p2, guint32 rgba) { SPCanvasItem *line = sp_canvas_item_new(sp_desktop_controls(this->desktop), SP_TYPE_CTRLLINE, NULL); @@ -1544,7 +1559,7 @@ new dragger and add it to draggers list void GrDrag::addDragger (GrDraggable *draggable) { - NR::Point p = sp_item_gradient_get_coords (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke); + Geom::Point p = sp_item_gradient_get_coords (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke); for (GList *i = this->draggers; i != NULL; i = i->next) { GrDragger *dragger = (GrDragger *) i->data; @@ -1694,7 +1709,7 @@ GrDrag::updateLines () if (SP_IS_LINEARGRADIENT (server)) { this->addLine (item, sp_item_gradient_get_coords (item, POINT_LG_BEGIN, 0, true), sp_item_gradient_get_coords (item, POINT_LG_END, 0, true), GR_LINE_COLOR_FILL); } else if (SP_IS_RADIALGRADIENT (server)) { - NR::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, 0, true); + Geom::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, 0, true); this->addLine (item, center, sp_item_gradient_get_coords (item, POINT_RG_R1, 0, true), GR_LINE_COLOR_FILL); this->addLine (item, center, sp_item_gradient_get_coords (item, POINT_RG_R2, 0, true), GR_LINE_COLOR_FILL); } @@ -1705,7 +1720,7 @@ GrDrag::updateLines () if (SP_IS_LINEARGRADIENT (server)) { this->addLine (item, sp_item_gradient_get_coords (item, POINT_LG_BEGIN, 0, false), sp_item_gradient_get_coords (item, POINT_LG_END, 0, false), GR_LINE_COLOR_STROKE); } else if (SP_IS_RADIALGRADIENT (server)) { - NR::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, 0, false); + Geom::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, 0, false); this->addLine (item, center, sp_item_gradient_get_coords (item, POINT_RG_R1, 0, false), GR_LINE_COLOR_STROKE); this->addLine (item, center, sp_item_gradient_get_coords (item, POINT_RG_R2, 0, false), GR_LINE_COLOR_STROKE); } @@ -1726,7 +1741,7 @@ GrDrag::updateLevels () for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); - boost::optional<Geom::Rect> rect = sp_item_bbox_desktop (item); + Geom::OptRect rect = sp_item_bbox_desktop (item); if (rect) { // Remember the edges of the bbox and the center axis hor_levels.push_back(rect->min()[Geom::Y]); @@ -1793,7 +1808,7 @@ GrDrag::selected_move (double x, double y, bool write_repr, bool scale_radial) } did = true; - d->point += NR::Point (x, y); + d->point += Geom::Point (x, y); d->point_original = d->point; sp_knot_moveto (d->knot, d->point); @@ -1816,16 +1831,16 @@ GrDrag::selected_move (double x, double y, bool write_repr, bool scale_radial) // a midpoint dragger can (logically) only contain one GrDraggable GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; - NR::Point begin(0,0), end(0,0); - NR::Point low_lim(0,0), high_lim(0,0); + Geom::Point begin(0,0), end(0,0); + Geom::Point low_lim(0,0), high_lim(0,0); SPObject *server = draggable->getServer(); GSList *moving = NULL; gr_midpoint_limits(dragger, server, &begin, &end, &low_lim, &high_lim, &moving); - NR::Point p(x, y); + Geom::Point p(x, y); p = snap_vector_midpoint (dragger->point + p, low_lim, high_lim, 0); - NR::Point displacement = p - dragger->point; + Geom::Point displacement = p - dragger->point; for (GSList const* i = moving; i != NULL; i = i->next) { GrDragger *drg = (GrDragger*) i->data; @@ -2003,13 +2018,13 @@ GrDrag::deleteSelected (bool just_one) SP_OBJECT_REPR(stopinfo->vector)->removeChild(SP_OBJECT_REPR(stopinfo->spstop)); SPLinearGradient *lg = SP_LINEARGRADIENT(stopinfo->gradient); - NR::Point oldbegin = NR::Point (lg->x1.computed, lg->y1.computed); - NR::Point end = NR::Point (lg->x2.computed, lg->y2.computed); + Geom::Point oldbegin = Geom::Point (lg->x1.computed, lg->y1.computed); + Geom::Point end = Geom::Point (lg->x2.computed, lg->y2.computed); SPStop *stop = sp_first_stop(stopinfo->vector); gdouble offset = stop->offset; - NR::Point newbegin = oldbegin + offset * (end - oldbegin); - lg->x1.computed = newbegin[NR::X]; - lg->y1.computed = newbegin[NR::Y]; + Geom::Point newbegin = oldbegin + offset * (end - oldbegin); + lg->x1.computed = newbegin[Geom::X]; + lg->y1.computed = newbegin[Geom::Y]; Inkscape::XML::Node *repr = SP_OBJECT_REPR(stopinfo->gradient); sp_repr_set_svg_double(repr, "x1", lg->x1.computed); @@ -2032,13 +2047,13 @@ GrDrag::deleteSelected (bool just_one) SP_OBJECT_REPR(stopinfo->vector)->removeChild(SP_OBJECT_REPR(stopinfo->spstop)); SPLinearGradient *lg = SP_LINEARGRADIENT(stopinfo->gradient); - NR::Point begin = NR::Point (lg->x1.computed, lg->y1.computed); - NR::Point oldend = NR::Point (lg->x2.computed, lg->y2.computed); + Geom::Point begin = Geom::Point (lg->x1.computed, lg->y1.computed); + Geom::Point oldend = Geom::Point (lg->x2.computed, lg->y2.computed); SPStop *laststop = sp_last_stop(stopinfo->vector); gdouble offset = laststop->offset; - NR::Point newend = begin + offset * (oldend - begin); - lg->x2.computed = newend[NR::X]; - lg->y2.computed = newend[NR::Y]; + Geom::Point newend = begin + offset * (oldend - begin); + lg->x2.computed = newend[Geom::X]; + lg->y2.computed = newend[Geom::Y]; Inkscape::XML::Node *repr = SP_OBJECT_REPR(stopinfo->gradient); sp_repr_set_svg_double(repr, "x2", lg->x2.computed); diff --git a/src/gradient-drag.h b/src/gradient-drag.h index acc2dd48f..974bba4de 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -20,6 +20,7 @@ #include <forward.h> #include <libnr/nr-forward.h> +#include <2geom/point.h> #include <knot-enums.h> struct SPItem; @@ -31,20 +32,20 @@ which has the gradient, whether it's fill or stroke, the point type (from the GrPointType enum), and the point number (needed if more than 2 stops are present). */ struct GrDraggable { - GrDraggable(SPItem *item, guint point_type, guint point_i, bool fill_or_stroke); + GrDraggable(SPItem *item, guint point_type, guint point_i, bool fill_or_stroke); virtual ~GrDraggable(); - SPItem *item; - gint point_type; - gint point_i; // the stop number of this point ( = 0 POINT_LG_BEGIN and POINT_RG_CENTER) - bool fill_or_stroke; + SPItem *item; + gint point_type; + gint point_i; // the stop number of this point ( = 0 POINT_LG_BEGIN and POINT_RG_CENTER) + bool fill_or_stroke; - SPObject *getServer(); + SPObject *getServer(); - bool mayMerge (GrDraggable *da2); + bool mayMerge (GrDraggable *da2); inline int equals (GrDraggable *other) { - return ((item == other->item) && (point_type == other->point_type) && (point_i == other->point_i) && (fill_or_stroke == other->fill_or_stroke)); + return ((item == other->item) && (point_type == other->point_type) && (point_i == other->point_i) && (fill_or_stroke == other->fill_or_stroke)); } }; @@ -56,45 +57,45 @@ be moved when the knot moves. Normally there's one draggable in the list, but th be more when draggers are snapped together. */ struct GrDragger { - GrDragger (GrDrag *parent, NR::Point p, GrDraggable *draggable); + GrDragger (GrDrag *parent, Geom::Point p, GrDraggable *draggable); virtual ~GrDragger(); - GrDrag *parent; + GrDrag *parent; - SPKnot *knot; + SPKnot *knot; - // position of the knot, desktop coords - NR::Point point; - // position of the knot before it began to drag; updated when released - NR::Point point_original; + // position of the knot, desktop coords + Geom::Point point; + // position of the knot before it began to drag; updated when released + Geom::Point point_original; - /** Connection to \a knot's "moved" signal, for blocking it (unused?). */ - guint handler_id; + /** Connection to \a knot's "moved" signal, for blocking it (unused?). */ + guint handler_id; - GSList *draggables; + GSList *draggables; - void addDraggable(GrDraggable *draggable); + void addDraggable(GrDraggable *draggable); - void updateKnotShape(); - void updateTip(); - - void select(); - void deselect(); - bool isSelected(); + void updateKnotShape(); + void updateTip(); + + void select(); + void deselect(); + bool isSelected(); - void moveThisToDraggable (SPItem *item, gint point_type, gint point_i, bool fill_or_stroke, bool write_repr); - void moveOtherToDraggable (SPItem *item, gint point_type, gint point_i, bool fill_or_stroke, bool write_repr); + void moveThisToDraggable (SPItem *item, gint point_type, gint point_i, bool fill_or_stroke, bool write_repr); + void moveOtherToDraggable (SPItem *item, gint point_type, gint point_i, bool fill_or_stroke, bool write_repr); void updateMidstopDependencies (GrDraggable *draggable, bool write_repr); void updateDependencies (bool write_repr); - bool mayMerge (GrDragger *other); - bool mayMerge (GrDraggable *da2); + bool mayMerge (GrDragger *other); + bool mayMerge (GrDraggable *da2); bool isA (gint point_type); bool isA (SPItem *item, gint point_type, bool fill_or_stroke); bool isA (SPItem *item, gint point_type, gint point_i, bool fill_or_stroke); - void fireDraggables (bool write_repr, bool scale_radial = false, bool merging_focus = false); + void fireDraggables (bool write_repr, bool scale_radial = false, bool merging_focus = false); }; /** @@ -107,26 +108,26 @@ public: // FIXME: make more of this private! GrDrag(SPDesktop *desktop); virtual ~GrDrag(); - bool isNonEmpty() {return (draggers != NULL);} - bool hasSelection() {return (selected != NULL);} - guint numSelected() {return (selected? g_list_length(selected) : 0);} - guint numDraggers() {return (draggers? g_list_length(draggers) : 0);} - guint singleSelectedDraggerNumDraggables() {return (selected? g_slist_length(((GrDragger *) selected->data)->draggables) : 0);} - guint singleSelectedDraggerSingleDraggableType() {return (selected? ((GrDraggable *) ((GrDragger *) selected->data)->draggables->data)->point_type : 0);} + bool isNonEmpty() {return (draggers != NULL);} + bool hasSelection() {return (selected != NULL);} + guint numSelected() {return (selected? g_list_length(selected) : 0);} + guint numDraggers() {return (draggers? g_list_length(draggers) : 0);} + guint singleSelectedDraggerNumDraggables() {return (selected? g_slist_length(((GrDragger *) selected->data)->draggables) : 0);} + guint singleSelectedDraggerSingleDraggableType() {return (selected? ((GrDraggable *) ((GrDragger *) selected->data)->draggables->data)->point_type : 0);} // especially the selection must be private, fix gradient-context to remove direct access to it GList *selected; // list of GrDragger* void setSelected (GrDragger *dragger, bool add_to_selection = false, bool override = true); void setDeselected (GrDragger *dragger); void deselectAll(); - void selectAll(); - void selectByCoords(std::vector<NR::Point> coords); + void selectAll(); + void selectByCoords(std::vector<Geom::Point> coords); void selectRect(Geom::Rect const &r); - bool dropColor(SPItem *item, gchar *c, NR::Point p); + bool dropColor(SPItem *item, gchar *c, Geom::Point p); + + SPStop *addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance); - SPStop *addStopNearPoint (SPItem *item, NR::Point mouse_p, double tolerance); - void deleteSelected (bool just_one = false); guint32 getColor(); @@ -165,7 +166,7 @@ public: // FIXME: make more of this private! private: void deselect_all(); - void addLine (SPItem *item, NR::Point p1, NR::Point p2, guint32 rgba); + void addLine (SPItem *item, Geom::Point p1, Geom::Point p2, guint32 rgba); void addDragger (GrDraggable *draggable); diff --git a/src/graphlayout/graphlayout.cpp b/src/graphlayout/graphlayout.cpp index 87ec60695..12bca8891 100644 --- a/src/graphlayout/graphlayout.cpp +++ b/src/graphlayout/graphlayout.cpp @@ -125,7 +125,7 @@ void graphlayout(GSList const *const items) { ++i) { SPItem *u=*i; - boost::optional<Geom::Rect> const item_box(sp_item_bbox_desktop(u)); + Geom::OptRect const item_box(sp_item_bbox_desktop(u)); if(item_box) { Geom::Point ll(item_box->min()); Geom::Point ur(item_box->max()); @@ -227,7 +227,7 @@ void graphlayout(GSList const *const items) { map<string,unsigned>::iterator i=nodelookup.find(u->id); if(i!=nodelookup.end()) { Rectangle* r=rs[i->second]; - boost::optional<Geom::Rect> item_box(sp_item_bbox_desktop(u)); + Geom::OptRect item_box(sp_item_bbox_desktop(u)); if(item_box) { Geom::Point const curr(item_box->midpoint()); Geom::Point const dest(r->getCentreX(),r->getCentreY()); diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert index 4d1ed6630..195ca2632 100644 --- a/src/helper/Makefile_insert +++ b/src/helper/Makefile_insert @@ -40,17 +40,21 @@ helper_libspchelp_a_SOURCES = \ helper/stock-items.cpp \ helper/stock-items.h - -# TODO: Check that the generated sp-marshal.h is the same as before. +# cmp exits with status 0 when there are no differences. if executes the commands +# after "then" when the exit status of the if command is 0 (this is crazy). helper/sp-marshal.h: helper/sp-marshal.list - glib-genmarshal --prefix=sp_marshal --header $(srcdir)/helper/sp-marshal.list > helper/tmp.$$$$ \ - && mv helper/tmp.$$$$ helper/sp-marshal.h + glib-genmarshal --prefix=sp_marshal --header $(srcdir)/helper/sp-marshal.list > helper/tmp.sp-marshal.h + if cmp -s helper/sp-marshal.h helper/tmp.sp-marshal.h; \ + then rm helper/tmp.sp-marshal.h; \ + else mv helper/tmp.sp-marshal.h helper/sp-marshal.h; fi helper/sp-marshal.cpp: helper/sp-marshal.list helper/sp-marshal.h ( echo '#include "helper/sp-marshal.h"' && \ glib-genmarshal --prefix=sp_marshal --body $(srcdir)/helper/sp-marshal.list ) \ - > helper/tmp.$$$$ \ - && mv helper/tmp.$$$$ helper/sp-marshal.cpp + > helper/tmp.sp-marshal.cpp; \ + if cmp -s helper/sp-marshal.cpp helper/tmp.sp-marshal.cpp; \ + then rm helper/tmp.sp-marshal.cpp; \ + else mv helper/tmp.sp-marshal.cpp helper/sp-marshal.cpp; fi helper/sp-marshal.cpp helper/sp-marshal.h: Makefile diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index 84f967860..c79cd829a 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -149,23 +149,21 @@ cubic_bbox (Geom::Coord x000, Geom::Coord y000, Geom::Coord x001, Geom::Coord y0 } } -Geom::Rect +Geom::OptRect bounds_fast_transformed(Geom::PathVector const & pv, Geom::Matrix const & t) { return bounds_exact_transformed(pv, t); //use this as it is faster for now! :) // return Geom::bounds_fast(pv * t); } -Geom::Rect +Geom::OptRect bounds_exact_transformed(Geom::PathVector const & pv, Geom::Matrix const & t) { - Geom::Rect bbox; - if (pv.empty()) - return bbox; + return Geom::OptRect(); Geom::Point initial = pv.front().initialPoint() * t; - bbox = Geom::Rect(initial, initial); // obtain well defined bbox as starting point to unionWith + Geom::Rect bbox(initial, initial); // obtain well defined bbox as starting point to unionWith for (Geom::PathVector::const_iterator it = pv.begin(); it != pv.end(); ++it) { bbox.expandTo(it->initialPoint() * t); @@ -494,6 +492,19 @@ pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv ) return output; } + +/** + * rounds all corners of the rectangle 'outwards', i.e. x0 and y0 are floored, x1 and y1 are ceiled. + */ +void round_rectangle_outwards(Geom::Rect & rect) { + Geom::Interval ints[2]; + for (int i=0; i < 2; i++) { + ints[i] = Geom::Interval(std::floor(rect[i][0]), std::ceil(rect[i][1])); + } + rect = Geom::Rect(ints[0], ints[1]); +} + + namespace Geom { bool transform_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon) { diff --git a/src/helper/geom.h b/src/helper/geom.h index 4cda22a1c..adf167392 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -16,8 +16,8 @@ #include <libnr/nr-forward.h> #include <libnr/nr-coord.h> -Geom::Rect bounds_fast_transformed(Geom::PathVector const & pv, Geom::Matrix const & t); -Geom::Rect bounds_exact_transformed(Geom::PathVector const & pv, Geom::Matrix const & t); +Geom::OptRect bounds_fast_transformed(Geom::PathVector const & pv, Geom::Matrix const & t); +Geom::OptRect bounds_exact_transformed(Geom::PathVector const & pv, Geom::Matrix const & t); void pathv_matrix_point_bbox_wind_distance ( Geom::PathVector const & pathv, Geom::Matrix const &m, Geom::Point const &pt, Geom::Rect *bbox, int *wind, Geom::Coord *dist, @@ -25,6 +25,8 @@ void pathv_matrix_point_bbox_wind_distance ( Geom::PathVector const & pathv, Geo Geom::PathVector pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv ); +void round_rectangle_outwards(Geom::Rect & rect); + /* The following predefined objects are for reference and comparison. They are defined in helper/geom.cpp diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index 89ab32f55..eb60169c4 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -19,6 +19,7 @@ #include <interface.h> #include <libnr/nr-pixops.h> #include <libnr/nr-translate-scale-ops.h> +#include <2geom/rect.h> #include <glib/gmessages.h> #include <png.h> #include "png-write.h" @@ -386,9 +387,20 @@ hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey) * * \return true if succeeded (or if no action was taken), false if an error occurred. */ +bool sp_export_png_file (SPDocument *doc, gchar const *filename, + double x0, double y0, double x1, double y1, + unsigned long int width, unsigned long int height, double xdpi, double ydpi, + unsigned long bgcolor, + unsigned int (*status) (float, void *), + void *data, bool force_overwrite, + GSList *items_only) +{ + return sp_export_png_file(doc, filename, Geom::Rect(Geom::Point(x0,y0),Geom::Point(x1,y1)), + width, height, xdpi, ydpi, bgcolor, status, data, force_overwrite, items_only); +} bool sp_export_png_file(SPDocument *doc, gchar const *filename, - double x0, double y0, double x1, double y1, + Geom::Rect const &area, unsigned long width, unsigned long height, double xdpi, double ydpi, unsigned long bgcolor, unsigned (*status)(float, void *), @@ -399,8 +411,22 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, g_return_val_if_fail(filename != NULL, false); g_return_val_if_fail(width >= 1, false); g_return_val_if_fail(height >= 1, false); + g_return_val_if_fail(!area.hasZeroArea(), false); + + //Make relative paths absolute, if possible: + gchar *path = 0; + if (!g_path_is_absolute(filename) && doc->uri) { + gchar *dirname = g_path_get_dirname(doc->uri); + if (dirname) { + path = g_build_filename(dirname, filename, NULL); + g_free(dirname); + } + } + if (!path) { + path = g_strdup(filename); + } - if (!force_overwrite && !sp_ui_overwrite_file(filename)) { + if (!force_overwrite && !sp_ui_overwrite_file(path)) { /* Remark: We return true so as not to invoke an error dialog in case export is cancelled by the user; currently this is safe because the callers only act when false is returned. If this changes in the future we need better distinction of return types (e.g., use int) @@ -417,14 +443,10 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, sp_document_ensure_up_to_date(doc); - /* Go to document coordinates */ - { - gdouble const t = y0; - y0 = sp_document_height(doc) - y1; - y1 = sp_document_height(doc) - t; - } + /* Calculate translation by transforming to document coordinates (flipping Y)*/ + Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - sp_document_height(doc)); - /* + /* This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2) * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0 * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0 * 3) a[0] * x1 + a[2] * y1 + a[4] = width @@ -440,9 +462,9 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, * (2) a[5] = -a[3] * y1 */ - Geom::Matrix const affine(Geom::Translate(-x0, -y0) - * Geom::Scale(width / (x1 - x0), - height / (y1 - y0))); + Geom::Matrix const affine(Geom::Translate(translation) + * Geom::Scale(width / area.width(), + height / area.height())); //SP_PRINT_MATRIX("SVG2PNG", &affine); @@ -475,12 +497,12 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, if ((width < 256) || ((width * height) < 32768)) { ebp.px = nr_pixelstore_64K_new(FALSE, 0); ebp.sheight = 65536 / (4 * width); - write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); + write_status = sp_png_write_rgba_striped(doc, path, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); nr_pixelstore_64K_free(ebp.px); } else { ebp.px = g_new(guchar, 4 * 64 * width); ebp.sheight = 64; - write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); + write_status = sp_png_write_rgba_striped(doc, path, width, height, xdpi, ydpi, sp_export_get_rows, &ebp); g_free(ebp.px); } @@ -494,6 +516,8 @@ sp_export_png_file(SPDocument *doc, gchar const *filename, prefs->setInt("/options/blurquality/value", saved_quality); prefs->setInt("/options/filterquality/value", saved_filter_quality); + g_free(path); + return write_status; } diff --git a/src/helper/png-write.h b/src/helper/png-write.h index 1217ba276..83321aa4e 100644 --- a/src/helper/png-write.h +++ b/src/helper/png-write.h @@ -13,6 +13,7 @@ */ #include <glib/gtypes.h> +#include <2geom/forward.h> struct SPDocument; bool sp_export_png_file (SPDocument *doc, gchar const *filename, @@ -20,5 +21,10 @@ bool sp_export_png_file (SPDocument *doc, gchar const *filename, unsigned long int width, unsigned long int height, double xdpi, double ydpi, unsigned long bgcolor, unsigned int (*status) (float, void *), void *data, bool force_overwrite = false, GSList *items_only = NULL); +bool sp_export_png_file (SPDocument *doc, gchar const *filename, + Geom::Rect const &area, + unsigned long int width, unsigned long int height, double xdpi, double ydpi, + unsigned long bgcolor, + unsigned int (*status) (float, void *), void *data, bool force_overwrite = false, GSList *items_only = NULL); #endif diff --git a/src/helper/recthull.h b/src/helper/recthull.h index 59649cfb6..a9cad4466 100644 --- a/src/helper/recthull.h +++ b/src/helper/recthull.h @@ -46,12 +46,12 @@ public: } } - boost::optional<Rect> const &bounds() const { + OptRect const &bounds() const { return _bounds; } private: - boost::optional<Rect> _bounds; + OptRect _bounds; }; } /* namespace Geom */ diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 51f740fb4..49b92394e 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1,9 +1,7 @@ -#define __INKSCAPE_C__ - -/* - * Interface to main application - * - * Authors: +/** @file + * @brief Legacy interface to main application + */ +/* Authors: * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * @@ -37,38 +35,33 @@ using Inkscape::Extension::Internal::PrintWin32; # include <shlobj.h> #endif -#include <signal.h> - -#include <gtk/gtkmain.h> -#include <gtk/gtkmessagedialog.h> -#include <glib.h> +#include <cstring> #include <glib/gstdio.h> - +#include <glib.h> #include <glibmm/i18n.h> +#include <gtk/gtkmain.h> +#include <gtk/gtkmessagedialog.h> +#include <signal.h> #include <string> -#include <cstring> -#include "helper/sp-marshal.h" -#include "dialogs/debugdialog.h" -#include "dialogs/input.h" #include "application/application.h" #include "application/editor.h" - - -#include "document.h" #include "desktop.h" #include "desktop-handles.h" -#include "selection.h" +#include "dialogs/input.h" +#include "document.h" #include "event-context.h" -#include "inkscape-private.h" -#include "xml/repr.h" -#include "preferences.h" -#include "io/sys.h" -#include "message-stack.h" - -#include "extension/init.h" #include "extension/db.h" +#include "extension/init.h" #include "extension/output.h" #include "extension/system.h" +#include "helper/sp-marshal.h" +#include "inkscape-private.h" +#include "io/sys.h" +#include "message-stack.h" +#include "preferences.h" +#include "selection.h" +#include "ui/dialog/debug.h" +#include "xml/repr.h" static Inkscape::Application *inkscape = NULL; @@ -774,7 +767,7 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) if (use_gui == TRUE && prefs->getBool("/dialogs/debug/redirect", DEFAULT_LOG_REDIRECT)) { - Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages(); + Inkscape::UI::Dialog::DebugDialog::getInstance()->captureLogMessages(); } /* Check for global remapping of Alt key */ diff --git a/src/interface.cpp b/src/interface.cpp index 8a3182103..fbdb8a5f6 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -20,6 +20,7 @@ #endif #include <gtk/gtk.h> +#include <glib.h> #include "inkscape-private.h" #include "extension/effect.h" #include "widgets/icon.h" @@ -926,7 +927,7 @@ sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI: // add filter to only open files added by Inkscape GtkRecentFilter *inkscape_only_filter = gtk_recent_filter_new(); - gtk_recent_filter_add_application(inkscape_only_filter, "inkscape"); + gtk_recent_filter_add_application(inkscape_only_filter, g_get_prgname()); gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(recent_menu), inkscape_only_filter); GtkWidget *recent_item = gtk_menu_item_new_with_mnemonic(_("Open _Recent")); @@ -1261,7 +1262,7 @@ sp_ui_drag_data_received(GtkWidget *widget, bool const saved_pref = prefs->getBool("/options/transform/pattern", true); prefs->setBool("/options/transform/pattern", true); sp_document_ensure_up_to_date(sp_desktop_document(desktop)); - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); sp_selection_move_relative(selection, m); diff --git a/src/libnr/nr-convert2geom.h b/src/libnr/nr-convert2geom.h index 7b501cddc..b7cbd7ee8 100644 --- a/src/libnr/nr-convert2geom.h +++ b/src/libnr/nr-convert2geom.h @@ -45,8 +45,8 @@ inline NR::Rect from_2geom(Geom::Rect const & rect2geom) { NR::Rect rect(rect2geom.min(), rect2geom.max()); return rect; } -inline boost::optional<Geom::Rect> to_2geom(boost::optional<NR::Rect> const & rect) { - boost::optional<Geom::Rect> rect2geom; +inline Geom::OptRect to_2geom(boost::optional<NR::Rect> const & rect) { + Geom::OptRect rect2geom; if (!rect) { return rect2geom; } diff --git a/src/libnr/nr-rect.cpp b/src/libnr/nr-rect.cpp index 620782996..1e1f36104 100644 --- a/src/libnr/nr-rect.cpp +++ b/src/libnr/nr-rect.cpp @@ -28,7 +28,7 @@ NRRect::NRRect(boost::optional<NR::Rect> const &rect) { } } -NRRect::NRRect(boost::optional<Geom::Rect> const &rect) { +NRRect::NRRect(Geom::OptRect const &rect) { if (rect) { x0 = rect->min()[Geom::X]; y0 = rect->min()[Geom::Y]; @@ -47,9 +47,9 @@ boost::optional<NR::Rect> NRRect::upgrade() const { } } -boost::optional<Geom::Rect> NRRect::upgrade_2geom() const { +Geom::OptRect NRRect::upgrade_2geom() const { if (nr_rect_d_test_empty_ptr(this)) { - return boost::optional<Geom::Rect>(); + return Geom::OptRect(); } else { return Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)); } diff --git a/src/libnr/nr-rect.h b/src/libnr/nr-rect.h index 83f780efd..c074b0034 100644 --- a/src/libnr/nr-rect.h +++ b/src/libnr/nr-rect.h @@ -244,9 +244,9 @@ struct NRRect { explicit NRRect(boost::optional<NR::Rect> const &rect); operator boost::optional<NR::Rect>() const { return upgrade(); } boost::optional<NR::Rect> upgrade() const; - explicit NRRect(boost::optional<Geom::Rect> const &rect); - operator boost::optional<Geom::Rect>() const { return upgrade_2geom(); } - boost::optional<Geom::Rect> upgrade_2geom() const; + explicit NRRect(Geom::OptRect const &rect); + operator Geom::OptRect() const { return upgrade_2geom(); } + Geom::OptRect upgrade_2geom() const; NR::Coord x0, y0, x1, y1; }; diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index d7d45b1e3..e1413b46e 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -615,7 +615,7 @@ bool font_instance::FontSlope(double &run, double &rise) return true; } -boost::optional<Geom::Rect> font_instance::BBox(int glyph_id) +Geom::OptRect font_instance::BBox(int glyph_id) { int no=-1; if ( id_to_no.find(glyph_id) == id_to_no.end() ) { @@ -629,7 +629,7 @@ boost::optional<Geom::Rect> font_instance::BBox(int glyph_id) no=id_to_no[glyph_id]; } if ( no < 0 ) { - return boost::optional<Geom::Rect>(); + return Geom::OptRect(); } else { Geom::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]); Geom::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]); diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 57be6033a..2e65c2b24 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -615,7 +615,6 @@ class Layout::Calculator iter_source_text++; char_index_in_unbroken_span++; char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); - glyph_rotate = 0.0; } advance_width *= direction_sign; @@ -1014,6 +1013,7 @@ unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source]; } if (text_source->rotate.size() > char_index_in_source) new_span.rotate = text_source->rotate[char_index_in_source]; + else if (char_index_in_source == 0) new_span.rotate = 0.f; if (input_index == 0 && para->unbroken_spans.empty() && !new_span.y._set && _flow._input_wrap_shapes.empty()) { // if we don't set an explicit y some of the automatic wrapping code takes over and moves the text vertically // so that the top of the letters is at zero, not the baseline diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index a5ae1cd81..2ee0051a4 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -54,6 +54,14 @@ void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_ _copyInputVector(optional_attributes->dx, optional_attributes_offset, &new_source->dx, new_source->text_length); _copyInputVector(optional_attributes->dy, optional_attributes_offset, &new_source->dy, new_source->text_length); _copyInputVector(optional_attributes->rotate, optional_attributes_offset, &new_source->rotate, new_source->text_length); + if (!optional_attributes->rotate.empty() && optional_attributes_offset >= optional_attributes->rotate.size()) { + SVGLength last_rotate; + last_rotate = 0.f; + for (std::vector<SVGLength>::const_iterator it = optional_attributes->rotate.begin() ; it != optional_attributes->rotate.end() ; ++it) + if (it->_set) + last_rotate = *it; + new_source->rotate.resize(1, last_rotate); + } } _input_stream.push_back(new_source); diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index abe282005..bbd4aa6fd 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -200,7 +200,7 @@ Layout::iterator Layout::sourceToIterator(void *source_cookie) const return sourceToIterator(source_cookie, Glib::ustring::const_iterator(std::string::const_iterator(NULL))); } -boost::optional<Geom::Rect> Layout::glyphBoundingBox(iterator const &it, double *rotation) const +Geom::OptRect Layout::glyphBoundingBox(iterator const &it, double *rotation) const { if (rotation) *rotation = _glyphs[it._glyph_index].rotation; return _glyphs[it._glyph_index].span(this).font->BBox(_glyphs[it._glyph_index].glyph); diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index a93993c56..49967cd59 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -117,7 +117,7 @@ void Layout::getBoundingBox(NRRect *bounding_box, Geom::Matrix const &transform, Geom::Matrix total_transform = glyph_matrix; total_transform *= transform; if(_glyphs[glyph_index].span(this).font) { - boost::optional<Geom::Rect> glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); + Geom::OptRect glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); if (glyph_rect) { Geom::Point bmi = glyph_rect->min(), bma = glyph_rect->max(); Geom::Point tlp(bmi[0],bmi[1]), trp(bma[0],bmi[1]), blp(bmi[0],bma[1]), brp(bma[0],bma[1]); diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 3d0c57288..19680b140 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -449,7 +449,7 @@ public: /** Returns the bounding box of the given glyph, and its rotation. The centre of rotation is the horizontal centre of the box at the text baseline. */ - boost::optional<Geom::Rect> glyphBoundingBox(iterator const &it, double *rotation) const; + Geom::OptRect glyphBoundingBox(iterator const &it, double *rotation) const; /** Returns the zero-based line number of the character pointed to by \a it. */ diff --git a/src/libnrtype/RasterFont.cpp b/src/libnrtype/RasterFont.cpp index 3fbbe62d7..14f6c7afa 100644 --- a/src/libnrtype/RasterFont.cpp +++ b/src/libnrtype/RasterFont.cpp @@ -107,7 +107,7 @@ void raster_font::BBox(int glyph_id,NRRect *area) { area->x0=area->y0=area->x1=area->y1=0; if ( daddy == NULL ) return; - boost::optional<Geom::Rect> res=daddy->BBox(glyph_id); + Geom::OptRect res=daddy->BBox(glyph_id); if (res) { Geom::Point bmi=res->min(),bma=res->max(); Geom::Point tlp(bmi[0],bmi[1]),trp(bma[0],bmi[1]),blp(bmi[0],bma[1]),brp(bma[0],bma[1]); diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 2c8340e8a..4209a20af 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -78,7 +78,7 @@ public: bool FontMetrics(double &ascent, double &descent, double &leading); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts - boost::optional<Geom::Rect> BBox(int glyph_id); + Geom::OptRect BBox(int glyph_id); // creates a rasterfont for the given style raster_font* RasterFont(Geom::Matrix const &trs, double stroke_width, diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp index 140157fe3..f2d2f2ff6 100644 --- a/src/line-snapper.cpp +++ b/src/line-snapper.cpp @@ -27,7 +27,7 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &/*f*/, - boost::optional<Geom::Rect> const &/*bbox_to_snap*/, + Geom::OptRect const &/*bbox_to_snap*/, std::vector<SPItem const *> const */*it*/, std::vector<Geom::Point> */*unselected_nodes*/) const { @@ -61,7 +61,7 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &/*f*/, - boost::optional<Geom::Rect> const &/*bbox_to_snap*/, + Geom::OptRect const &/*bbox_to_snap*/, ConstraintLine const &c, std::vector<SPItem const *> const */*it*/) const diff --git a/src/line-snapper.h b/src/line-snapper.h index 593e8bd73..529db1caa 100644 --- a/src/line-snapper.h +++ b/src/line-snapper.h @@ -28,7 +28,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, std::vector<SPItem const *> const *it, std::vector<Geom::Point> *unselected_nodes) const; @@ -36,7 +36,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, ConstraintLine const &c, std::vector<SPItem const *> const *it) const; diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 98875a5a2..89b7b9e3a 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -11,6 +11,7 @@ lpe-gears.cpp lpegroupbbox.cpp lpe-interpolate.cpp lpe-knot.cpp +lpe-hatches.cpp lpe-lattice.cpp lpe-mirror_symmetry.cpp lpeobject.cpp diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 3b136d204..1bb001778 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -8,6 +8,7 @@ live_effects/clean: live_effects_liblive_effects_a_SOURCES = \ live_effects/effect.cpp \ live_effects/effect.h \ + live_effects/effect-enum.h \ live_effects/lpeobject.cpp \ live_effects/lpeobject.h \ live_effects/lpegroupbbox.cpp \ @@ -26,6 +27,8 @@ live_effects_liblive_effects_a_SOURCES = \ live_effects/lpe-knot.h \ live_effects/lpe-vonkoch.cpp \ live_effects/lpe-vonkoch.h \ + live_effects/lpe-hatches.cpp \ + live_effects/lpe-hatches.h \ live_effects/lpe-curvestitch.cpp \ live_effects/lpe-curvestitch.h \ live_effects/lpe-constructgrid.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h new file mode 100644 index 000000000..1e82954f8 --- /dev/null +++ b/src/live_effects/effect-enum.h @@ -0,0 +1,72 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_ENUM_H +#define INKSCAPE_LIVEPATHEFFECT_ENUM_H + +/* + * Inkscape::LivePathEffect::EffectType + * +* Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "util/enums.h" + +#define LPE_ENABLE_TEST_EFFECTS + +namespace Inkscape { +namespace LivePathEffect { + +enum EffectType { + BEND_PATH = 0, + PATTERN_ALONG_PATH, + FREEHAND_SHAPE, + SKETCH, + HATCHES, + VONKOCH, + KNOT, +#ifdef LPE_ENABLE_TEST_EFFECTS + DOEFFECTSTACK_TEST, +#endif + GEARS, + CURVE_STITCH, + CIRCLE_WITH_RADIUS, + PERSPECTIVE_PATH, + SPIRO, + LATTICE, + ENVELOPE, + CONSTRUCT_GRID, + PERP_BISECTOR, + TANGENT_TO_CURVE, + MIRROR_SYMMETRY, + CIRCLE_3PTS, + ANGLE_BISECTOR, + PARALLEL, + COPY_ROTATE, + OFFSET, + RULER, + BOOLOPS, + INTERPOLATE, + TEXT_LABEL, + PATH_LENGTH, + LINE_SEGMENT, + INVALID_LPE // This must be last +}; + +extern const Util::EnumData<EffectType> LPETypeData[]; /// defined in effect.cpp +extern const Util::EnumDataConverter<EffectType> LPETypeConverter; /// defined in effect.cpp + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif + +/* + 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/effect.cpp b/src/live_effects/effect.cpp index a04100cd3..bb5f0c554 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -42,6 +42,7 @@ #include "live_effects/lpe-sketch.h" #include "live_effects/lpe-vonkoch.h" #include "live_effects/lpe-knot.h" +#include "live_effects/lpe-hatches.h" #include "live_effects/lpe-test-doEffect-stack.h" #include "live_effects/lpe-gears.h" #include "live_effects/lpe-curvestitch.h" @@ -99,6 +100,7 @@ const Util::EnumData<EffectType> LPETypeData[] = { {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, {RULER, N_("Ruler"), "ruler"}, {SKETCH, N_("Sketch"), "sketch"}, + {HATCHES, N_("Hatches"), "hatches"}, {SPIRO, N_("Spiro spline"), "spiro"}, {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, @@ -137,6 +139,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case SKETCH: neweffect = static_cast<Effect*> ( new LPESketch(lpeobj) ); break; + case HATCHES: + neweffect = static_cast<Effect*> ( new LPEHatches(lpeobj) ); + break; case VONKOCH: neweffect = static_cast<Effect*> ( new LPEVonKoch(lpeobj) ); break; @@ -663,10 +668,9 @@ Effect::providesKnotholder() if (kh_entity_vector.size() > 0) return true; - // otherwise: are there any PointParams? + // otherwise: are there any parameters that have knotholderentities? for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { -// if ( Inkscape::LivePathEffect::PointParam *pointparam = dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p) ) { - if (dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p)) { + if ((*p)->providesKnotHolderEntities()) { return true; } } diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 8dd1354e2..ae42e358c 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -16,15 +16,13 @@ #include <2geom/path.h> #include <2geom/forward.h> #include "ui/widget/registry.h" -#include "util/enums.h" #include "sp-lpe-item.h" #include "knotholder.h" #include "parameter/bool.h" +#include "effect-enum.h" #define LPE_CONVERSION_TOLERANCE 0.01 // FIXME: find good solution for this. -#define LPE_ENABLE_TEST_EFFECTS - struct SPDocument; struct SPDesktop; struct SPItem; @@ -49,44 +47,6 @@ namespace NodePath { namespace LivePathEffect { -enum EffectType { - BEND_PATH = 0, - PATTERN_ALONG_PATH, - FREEHAND_SHAPE, - SKETCH, - VONKOCH, - KNOT, -#ifdef LPE_ENABLE_TEST_EFFECTS - DOEFFECTSTACK_TEST, -#endif - GEARS, - CURVE_STITCH, - CIRCLE_WITH_RADIUS, - PERSPECTIVE_PATH, - SPIRO, - LATTICE, - ENVELOPE, - CONSTRUCT_GRID, - PERP_BISECTOR, - TANGENT_TO_CURVE, - MIRROR_SYMMETRY, - CIRCLE_3PTS, - ANGLE_BISECTOR, - PARALLEL, - COPY_ROTATE, - OFFSET, - RULER, - BOOLOPS, - INTERPOLATE, - TEXT_LABEL, - PATH_LENGTH, - LINE_SEGMENT, - INVALID_LPE // This must be last -}; - -extern const Util::EnumData<EffectType> LPETypeData[]; -extern const Util::EnumDataConverter<EffectType> LPETypeConverter; - enum LPEPathFlashType { SUPPRESS_FLASH, // PERMANENT_FLASH, diff --git a/src/live_effects/lpe-circle_with_radius.cpp b/src/live_effects/lpe-circle_with_radius.cpp index 8b169af3c..574a9c004 100644 --- a/src/live_effects/lpe-circle_with_radius.cpp +++ b/src/live_effects/lpe-circle_with_radius.cpp @@ -1,20 +1,11 @@ -#define INKSCAPE_LPE_CIRCLE_WITH_RADIUS_CPP -/** \file - * LPE <circle_with_radius> implementation, used as an example for a base starting class - * when implementing new LivePathEffects. - * - * In vi, three global search-and-replaces will let you rename everything - * in this and the .h file: - * - * :%s/CIRCLE_WITH_RADIUS/YOURNAME/g - * :%s/CircleWithRadius/Yourname/g - * :%s/circle_with_radius/yourname/g +/** @file + * @brief LPE effect that draws a circle based on two points and a radius + * - implementation */ -/* - * Authors: - * Johan Engelen -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -106,4 +97,4 @@ LPECircleWithRadius::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & p fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-circle_with_radius.h b/src/live_effects/lpe-circle_with_radius.h index 19330eb33..2b9494875 100644 --- a/src/live_effects/lpe-circle_with_radius.h +++ b/src/live_effects/lpe-circle_with_radius.h @@ -1,19 +1,17 @@ -#ifndef INKSCAPE_LPE_CIRCLE_WITH_RADIUS_H -#define INKSCAPE_LPE_CIRCLE_WITH_RADIUS_H - -/** \file - * LPE <circle_with_radius> implementation, see lpe-circle_with_radius.cpp. +/** @file + * @brief LPE effect that draws a circle based on two points and a radius */ - -/* - * Authors: - * Johan Engelen -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef INKSCAPE_LPE_CIRCLE_WITH_RADIUS_H +#define INKSCAPE_LPE_CIRCLE_WITH_RADIUS_H + #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/path.h" @@ -43,3 +41,14 @@ private: } //namespace Inkscape #endif + +/* + 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/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp index 4404620be..2716e45d7 100644 --- a/src/live_effects/lpe-curvestitch.cpp +++ b/src/live_effects/lpe-curvestitch.cpp @@ -79,10 +79,13 @@ LPECurveStitch::doEffect_path (std::vector<Geom::Path> const & path_in) endpoint_spacing_variation.resetRandomizer(); D2<Piecewise<SBasis> > stroke = make_cuts_independent(strokepath.get_pwd2()); - Interval bndsStroke = bounds_exact(stroke[0]); - gdouble scaling = bndsStroke.max() - bndsStroke.min(); - Interval bndsStrokeY = bounds_exact(stroke[1]); - Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2); + OptInterval bndsStroke = bounds_exact(stroke[0]); + OptInterval bndsStrokeY = bounds_exact(stroke[1]); + if (!bndsStroke && !bndsStrokeY) { + return path_in; + } + gdouble scaling = bndsStroke->max() - bndsStroke->min(); + Point stroke_origin(bndsStroke->min(), (bndsStrokeY->max()+bndsStrokeY->min())/2); std::vector<Geom::Path> path_out; @@ -163,18 +166,22 @@ LPECurveStitch::resetDefaults(SPItem * item) pwd2.concat( temppath[i].toPwSb() ); } D2<Piecewise<SBasis> > d2pw = make_cuts_independent(pwd2); - Interval bndsX = bounds_exact(d2pw[0]); - Interval bndsY = bounds_exact(d2pw[1]); - Point start(bndsX.min(), (bndsY.max()+bndsY.min())/2); - Point end(bndsX.max(), (bndsY.max()+bndsY.min())/2); - - if ( !Geom::are_near(start,end) ) { - Geom::Path path; - path.start( start ); - path.appendNew<Geom::LineSegment>( end ); - strokepath.set_new_value( path.toPwSb(), true ); + OptInterval bndsX = bounds_exact(d2pw[0]); + OptInterval bndsY = bounds_exact(d2pw[1]); + if (bndsX && bndsY) { + Point start(bndsX->min(), (bndsY->max()+bndsY->min())/2); + Point end(bndsX->max(), (bndsY->max()+bndsY->min())/2); + if ( !Geom::are_near(start,end) ) { + Geom::Path path; + path.start( start ); + path.appendNew<Geom::LineSegment>( end ); + strokepath.set_new_value( path.toPwSb(), true ); + } else { + // bounding box is too small to make decent path. set to default default. :-) + strokepath.param_set_and_write_default(); + } } else { - // bounding box is too small to make decent path. set to default default. :-) + // bounding box is non-existent. set to default default. :-) strokepath.param_set_and_write_default(); } } diff --git a/src/live_effects/lpe-hatches.cpp b/src/live_effects/lpe-hatches.cpp new file mode 100644 index 000000000..2205d91f3 --- /dev/null +++ b/src/live_effects/lpe-hatches.cpp @@ -0,0 +1,593 @@ +#define INKSCAPE_LPE_HATCHES_CPP
+/** \file
+ * LPE Curve Stitching implementation, used as an example for a base starting class
+ * when implementing new LivePathEffects.
+ *
+ */
+/*
+ * Authors:
+ * JF Barraud.
+*
+* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-hatches.h"
+
+#include "sp-item.h"
+#include "sp-path.h"
+#include "svg/svg.h"
+#include "xml/repr.h"
+
+#include <2geom/path.h>
+#include <2geom/piecewise.h>
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-math.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+#include <2geom/matrix.h>
+
+#include "ui/widget/scalar.h"
+#include "libnr/nr-values.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+using namespace Geom;
+
+//------------------------------------------------
+// Some goodies to navigate through curve's levels.
+//------------------------------------------------
+struct LevelCrossing{
+ Point pt;
+ double t;
+ bool sign;
+ bool used;
+ std::pair<unsigned,unsigned> next_on_curve;
+ std::pair<unsigned,unsigned> prev_on_curve;
+};
+struct LevelCrossingOrder {
+ bool operator()(LevelCrossing a, LevelCrossing b) {
+ return a.pt[Y] < b.pt[Y];
+ }
+};
+struct LevelCrossingInfo{
+ double t;
+ unsigned level;
+ unsigned idx;
+};
+struct LevelCrossingInfoOrder {
+ bool operator()(LevelCrossingInfo a, LevelCrossingInfo b) {
+ return a.t < b.t;
+ }
+};
+
+typedef std::vector<LevelCrossing> LevelCrossings;
+
+std::vector<double>
+discontinuities(Piecewise<D2<SBasis> > const &f){
+ std::vector<double> result;
+ if (f.size()==0) return result;
+ result.push_back(f.cuts[0]);
+ Point prev_pt = f.segs[0].at1();
+ //double old_t = f.cuts[0];
+ for(unsigned i=1; i<f.size(); i++){
+ if ( f.segs[i].at0()!=prev_pt){
+ result.push_back(f.cuts[i]);
+ //old_t = f.cuts[i];
+ //assert(f.segs[i-1].at1()==f.valueAt(old_t));
+ }
+ prev_pt = f.segs[i].at1();
+ }
+ result.push_back(f.cuts.back());
+ //assert(f.segs.back().at1()==f.valueAt(old_t));
+ return result;
+}
+
+class LevelsCrossings: public std::vector<LevelCrossings>{
+public:
+ LevelsCrossings():std::vector<LevelCrossings>(){};
+ LevelsCrossings(std::vector<std::vector<double> > const ×,
+ Piecewise<D2<SBasis> > const &f,
+ Piecewise<SBasis> const &dx){
+
+ for (unsigned i=0; i<times.size(); i++){
+ LevelCrossings lcs;
+ for (unsigned j=0; j<times[i].size(); j++){
+ LevelCrossing lc;
+ lc.pt = f.valueAt(times[i][j]);
+ lc.t = times[i][j];
+ lc.sign = ( dx.valueAt(times[i][j])>0 );
+ lc.used = false;
+ lcs.push_back(lc);
+ }
+ std::sort(lcs.begin(), lcs.end(), LevelCrossingOrder());
+ push_back(lcs);
+ }
+ //Now create time ordering.
+ std::vector<LevelCrossingInfo>temp;
+ for (unsigned i=0; i<size(); i++){
+ for (unsigned j=0; j<(*this)[i].size(); j++){
+ LevelCrossingInfo elem;
+ elem.t = (*this)[i][j].t;
+ elem.level = i;
+ elem.idx = j;
+ temp.push_back(elem);
+ }
+ }
+ std::sort(temp.begin(),temp.end(),LevelCrossingInfoOrder());
+ std::vector<double> jumps = discontinuities(f);
+ unsigned jump_idx = 0;
+ unsigned first_in_comp = 0;
+ for (unsigned i=0; i<temp.size(); i++){
+ unsigned lvl = temp[i].level, idx = temp[i].idx;
+ if ( i == temp.size()-1 || temp[i+1].t > jumps[jump_idx+1]){
+ std::pair<unsigned,unsigned>next_data(temp[first_in_comp].level,temp[first_in_comp].idx);
+ (*this)[lvl][idx].next_on_curve = next_data;
+ first_in_comp = i+1;
+ jump_idx += 1;
+ }else{
+ std::pair<unsigned,unsigned> next_data(temp[i+1].level,temp[i+1].idx);
+ (*this)[lvl][idx].next_on_curve = next_data;
+ }
+ }
+
+ for (unsigned i=0; i<size(); i++){
+ for (unsigned j=0; j<(*this)[i].size(); j++){
+ std::pair<unsigned,unsigned> next = (*this)[i][j].next_on_curve;
+ (*this)[next.first][next.second].prev_on_curve = std::pair<unsigned,unsigned>(i,j);
+ }
+ }
+#if 0
+ std::cout<<"\n";
+ for (unsigned i=0; i<temp.size()-1; i++){
+ std::cout<<temp[i].level<<","<<temp[i].idx<<" -> ";
+ }
+ std::cout<<"\n";
+ for (unsigned i=0; i<size(); i++){
+ for (unsigned j=0; j<(*this)[i].size(); j++){
+ std::cout<<"level:"<<i<<", idx:"<<j<<" - ";
+ std::cout<<"next:"<<(*this)[i][j].next_on_curve.first<<",";
+ std::cout<<(*this)[i][j].next_on_curve.second<<" - ";
+ std::cout<<"prev:"<<(*this)[i][j].prev_on_curve.first<<",";
+ std::cout<<(*this)[i][j].prev_on_curve.second<<"\n";
+ }
+ }
+#endif
+ }
+
+ void findFirstUnused(unsigned &level, unsigned &idx){
+ level = size();
+ idx = 0;
+ for (unsigned i=0; i<size(); i++){
+ for (unsigned j=0; j<(*this)[i].size(); j++){
+ if (!(*this)[i][j].used){
+ level = i;
+ idx = j;
+ return;
+ }
+ }
+ }
+ }
+ //set indexes to point to the next point in the "snake walk"
+ //follow_level's meaning:
+ // 0=yes upward
+ // 1=no, last move was upward,
+ // 2=yes downward
+ // 3=no, last move was downward.
+ void step(unsigned &level, unsigned &idx, int &direction){
+ if ( direction % 2 == 0 ){
+ if (direction == 0) {
+ if ( idx >= (*this)[level].size()-1 || (*this)[level][idx+1].used ) {
+ level = size();
+ return;
+ }
+ idx += 1;
+ }else{
+ if ( idx <= 0 || (*this)[level][idx-1].used ) {
+ level = size();
+ return;
+ }
+ idx -= 1;
+ }
+ direction += 1;
+ return;
+ }
+ double t = (*this)[level][idx].t;
+ double sign = ((*this)[level][idx].sign ? 1 : -1);
+ double next_t = t;
+ //level += 1;
+ direction = (direction + 1)%4;
+ if (level == size()){
+ return;
+ }
+
+ std::pair<unsigned,unsigned> next;
+ if ( sign > 0 ){
+ next = (*this)[level][idx].next_on_curve;
+ }else{
+ next = (*this)[level][idx].prev_on_curve;
+ }
+
+ if ( level+1 != next.first || (*this)[next.first][next.second].used ) {
+ level = size();
+ return;
+ }
+ level = next.first;
+ idx = next.second;
+
+/*********************
+ //look for next time on the same level
+ for (unsigned j=0; j<(*this)[level].size(); j++){
+ double tj = (*this)[level][j].t;
+ if ( sign*(tj-t) > 0 ){
+ if( next_t == t || sign*(tj-next_t)<0 ){
+ next_t = tj;
+ idx = j;
+ }
+ }
+ }
+ if ( next_t == t ){//not found? look at max/min time in this component, as time is "periodic".
+ for (unsigned j=0; j<(*this)[level].size(); j++){
+ double tj = (*this)[level][j].t;
+ if ( -sign*(tj-next_t) > 0 ){
+ next_t = tj;
+ idx = j;
+ }
+ }
+ }
+ if ( next_t == t ){//still not found? houch! this should not happen.
+ level = size();
+ return;
+ }
+ if ( (*this)[level][idx].used ) {
+ level = size();
+ return;
+ }
+*************************/
+ return;
+ }
+};
+
+//-------------------------------------------------------
+// Bend a path...
+//-------------------------------------------------------
+
+Piecewise<D2<SBasis> > bend(Piecewise<D2<SBasis> > const &f, Piecewise<SBasis> bending){
+ D2<Piecewise<SBasis> > ff = make_cuts_independent(f);
+ ff[X] += compose(bending, ff[Y]);
+ return sectionize(ff);
+}
+
+//--------------------------------------------------------
+// The Hatches lpe.
+//--------------------------------------------------------
+LPEHatches::LPEHatches(LivePathEffectObject *lpeobject) :
+ Effect(lpeobject),
+ dist_rdm(_("Dist randomness"), _("Variation of dist between hatches, in %."), "dist_rdm", &wr, this, 75),
+ growth(_("Growth"), _("Growth of distance between hatches."), "growth", &wr, this, 0.),
+ scale_tf(_("Start smothness (front side)"), _("MISSING DESCRIPTION"), "scale_tf", &wr, this, 1.),
+ scale_tb(_("Start smothness (back side)"), _("MISSING DESCRIPTION"), "scale_tb", &wr, this, 1.),
+ scale_bf(_("End smothness (front side)"), _("MISSING DESCRIPTION"), "scale_bf", &wr, this, 1.),
+ scale_bb(_("End smothness (back side)"), _("MISSING DESCRIPTION"), "scale_bb", &wr, this, 1.),
+ top_edge_variation(_("Start edge variance"), _("The amount of random jitter to move the hatches start"), "top_edge_variation", &wr, this, 0),
+ bot_edge_variation(_("End edge variance"), _("The amount of random jitter to move the hatches end"), "bot_edge_variation", &wr, this, 0),
+ top_tgt_variation(_("Start tangential variance"), _("The amount of random jitter to move the hatches start along the boundary"), "top_tgt_variation", &wr, this, 0),
+ bot_tgt_variation(_("End tangential variance"), _("The amount of random jitter to move the hatches end along the boundary"), "bot_tgt_variation", &wr, this, 0),
+ top_smth_variation(_("Start smoothness variance"), _("Randomness of the smoothness of the U turn at hatches start"), "top_smth_variation", &wr, this, 0),
+ bot_smth_variation(_("End spacing variance"), _("Randomness of the smoothness of the U turn at hatches end"), "bot_smth_variation", &wr, this, 0),
+ fat_output(_("Generate thick/thin path"), _("Simulate a stroke of varrying width"), "fat_output", &wr, this, true),
+ do_bend(_("Bend hatches"), _("Add a global bend to the hatches (slower)"), "do_bend", &wr, this, true),
+ stroke_width_top(_("Stroke width (start side)"), _("Width at hatches 'start'"), "stroke_width_top", &wr, this, 1.),
+ stroke_width_bot(_("Stroke width (end side)"), _("Width at hatches 'end'"), "stroke_width_bot", &wr, this, 1.),
+ front_thickness(_("Front thickness (%)"), _("MISSING DESCRIPTION"), "front_thickness", &wr, this, 1.),
+ back_thickness(_("Back thickness (%)"), _("MISSING DESCRIPTION"), "back_thickness", &wr, this, .25),
+ bender(_("Global bending"), _("Relative position to ref point defines global bending direction and amount"), "bender", &wr, this, NULL, Geom::Point(-5,0)),
+ direction(_("Hatches width and dir"), _("Defines hatches frequency and direction"), "direction", &wr, this, Geom::Point(50,0))
+{
+ registerParameter( dynamic_cast<Parameter *>(&direction) );
+ registerParameter( dynamic_cast<Parameter *>(&do_bend) );
+ registerParameter( dynamic_cast<Parameter *>(&bender) );
+ registerParameter( dynamic_cast<Parameter *>(&dist_rdm) );
+ registerParameter( dynamic_cast<Parameter *>(&growth) );
+ registerParameter( dynamic_cast<Parameter *>(&top_edge_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&bot_edge_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&top_tgt_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&bot_tgt_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&scale_tf) );
+ registerParameter( dynamic_cast<Parameter *>(&scale_tb) );
+ registerParameter( dynamic_cast<Parameter *>(&scale_bf) );
+ registerParameter( dynamic_cast<Parameter *>(&scale_bb) );
+ registerParameter( dynamic_cast<Parameter *>(&top_smth_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&bot_smth_variation) );
+ registerParameter( dynamic_cast<Parameter *>(&fat_output) );
+ registerParameter( dynamic_cast<Parameter *>(&stroke_width_top) );
+ registerParameter( dynamic_cast<Parameter *>(&stroke_width_bot) );
+ registerParameter( dynamic_cast<Parameter *>(&front_thickness) );
+ registerParameter( dynamic_cast<Parameter *>(&back_thickness) );
+
+ //hatch_dist.param_set_range(0.1, NR_HUGE);
+ growth.param_set_range(-0.95, NR_HUGE);
+ dist_rdm.param_set_range(0, 99.);
+ stroke_width_top.param_set_range(0, NR_HUGE);
+ stroke_width_bot.param_set_range(0, NR_HUGE);
+ front_thickness.param_set_range(0, NR_HUGE);
+ back_thickness.param_set_range(0, NR_HUGE);
+
+ concatenate_before_pwd2 = true;
+ show_orig_path = true;
+}
+
+LPEHatches::~LPEHatches()
+{
+
+}
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPEHatches::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in){
+
+ Piecewise<D2<SBasis> > result;
+
+ Piecewise<D2<SBasis> > transformed_pwd2_in = pwd2_in;
+ Piecewise<SBasis> tilter;//used to bend the hatches
+ Matrix bend_mat;//used to bend the hatches
+
+ if (do_bend.get_value()){
+ Point bend_dir = -rot90(unit_vector(direction.getOrigin() - bender));
+ double bend_amount = L2(direction.getOrigin() - bender);
+ bend_mat = Matrix(-bend_dir[Y], bend_dir[X], bend_dir[X], bend_dir[Y],0,0);
+ transformed_pwd2_in = pwd2_in * bend_mat;
+ tilter = Piecewise<SBasis>(shift(Linear(bend_amount),1));
+ OptRect bbox = bounds_exact( transformed_pwd2_in );
+ if (not(bbox)) return pwd2_in;
+ tilter.setDomain((*bbox)[Y]);
+ transformed_pwd2_in = bend(transformed_pwd2_in, tilter);
+ transformed_pwd2_in = transformed_pwd2_in * bend_mat.inverse();
+ }
+ hatch_dist = Geom::L2(direction.getVector())/5;
+ Point hatches_dir = rot90(unit_vector(direction.getVector()));
+ Matrix mat(-hatches_dir[Y], hatches_dir[X], hatches_dir[X], hatches_dir[Y],0,0);
+ transformed_pwd2_in = transformed_pwd2_in * mat;
+
+ std::vector<std::vector<Point> > snakePoints;
+ snakePoints = linearSnake(transformed_pwd2_in);
+ if ( snakePoints.size() > 0 ){
+ Piecewise<D2<SBasis> >smthSnake = smoothSnake(snakePoints);
+ smthSnake = smthSnake*mat.inverse();
+ if (do_bend.get_value()){
+ smthSnake = smthSnake*bend_mat;
+ smthSnake = bend(smthSnake, -tilter);
+ smthSnake = smthSnake*bend_mat.inverse();
+ }
+ return (smthSnake);
+ }
+ return pwd2_in;
+}
+
+//------------------------------------------------
+// Generate the levels with random, growth...
+//------------------------------------------------
+std::vector<double>
+LPEHatches::generateLevels(Interval const &domain){
+ std::vector<double> result;
+ double x = domain.min() + double(hatch_dist)/2.;
+ double step = double(hatch_dist);
+ double scale = 1+(hatch_dist*growth/domain.extent());
+ while (x < domain.max()){
+ result.push_back(x);
+ double rdm = 1;
+ if (dist_rdm.get_value() != 0)
+ rdm = 1.+ double((2*dist_rdm - dist_rdm.get_value()))/100.;
+ x+= step*rdm;
+ step*=scale;//(1.+double(growth));
+ }
+ return result;
+}
+
+
+//-------------------------------------------------------
+// Walk through the intersections to create linear hatches
+//-------------------------------------------------------
+std::vector<std::vector<Point> >
+LPEHatches::linearSnake(Piecewise<D2<SBasis> > const &f){
+
+ std::vector<std::vector<Point> > result;
+
+ Piecewise<SBasis> x = make_cuts_independent(f)[X];
+ //Rque: derivative is computed twice in the 2 lines below!!
+ Piecewise<SBasis> dx = derivative(x);
+ OptInterval range = bounds_exact(x);
+
+ if (not range) return result;
+ std::vector<double> levels = generateLevels(*range);
+ std::vector<std::vector<double> > times;
+ times = multi_roots(x,levels);
+
+//TODO: fix multi_roots!!!*****************************************
+//remove doubles :-(
+ std::vector<std::vector<double> > cleaned_times(levels.size(),std::vector<double>());
+ for (unsigned i=0; i<times.size(); i++){
+ if ( times[i].size()>0 ){
+ double last_t = times[i][0]-1;//ugly hack!!
+ for (unsigned j=0; j<times[i].size(); j++){
+ if (times[i][j]-last_t >0.000001){
+ last_t = times[i][j];
+ cleaned_times[i].push_back(last_t);
+ }
+ }
+ }
+ }
+ times = cleaned_times;
+// for (unsigned i=0; i<times.size(); i++){
+// std::cout << "roots on level "<<i<<": ";
+// for (unsigned j=0; j<times[i].size(); j++){
+// std::cout << times[i][j] <<" ";
+// }
+// std::cout <<"\n";
+// }
+//*******************************************************************
+ LevelsCrossings lscs(times,f,dx);
+ unsigned i,j;
+ lscs.findFirstUnused(i,j);
+ std::vector<Point> result_component;
+ while ( i < lscs.size() ){
+ int dir = 0;
+ while ( i < lscs.size() ){
+ result_component.push_back(lscs[i][j].pt);
+ lscs[i][j].used = true;
+ lscs.step(i,j, dir);
+ }
+ result.push_back(result_component);
+ result_component = std::vector<Point>();
+ lscs.findFirstUnused(i,j);
+ }
+ return result;
+}
+
+//-------------------------------------------------------
+// Smooth the linear hatches according to params...
+//-------------------------------------------------------
+Piecewise<D2<SBasis> >
+LPEHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake){
+
+ Piecewise<D2<SBasis> > result;
+ for (unsigned comp=0; comp<linearSnake.size(); comp++){
+ if (linearSnake[comp].size()>=2){
+ bool is_top = true;//Inversion here; due to downward y?
+ Point last_pt = linearSnake[comp][0];
+ Point last_top = linearSnake[comp][0];
+ Point last_bot = linearSnake[comp][0];
+ Point last_hdle = linearSnake[comp][0];
+ Point last_top_hdle = linearSnake[comp][0];
+ Point last_bot_hdle = linearSnake[comp][0];
+ Geom::Path res_comp(last_pt);
+ Geom::Path res_comp_top(last_pt);
+ Geom::Path res_comp_bot(last_pt);
+ unsigned i=1;
+ while( i+1<linearSnake[comp].size() ){
+ Point pt0 = linearSnake[comp][i];
+ Point pt1 = linearSnake[comp][i+1];
+ Point new_pt = (pt0+pt1)/2;
+ double scale_in = (is_top ? scale_tf : scale_bf );
+ double scale_out = (is_top ? scale_tb : scale_bb );
+ if (is_top){
+ if (top_edge_variation.get_value() != 0)
+ new_pt[Y] += double(top_edge_variation)-top_edge_variation.get_value()/2.;
+ if (top_tgt_variation.get_value() != 0)
+ new_pt[X] += double(top_tgt_variation)-top_tgt_variation.get_value()/2.;
+ if (top_smth_variation.get_value() != 0) {
+ scale_in*=(100.-double(top_smth_variation))/100.;
+ scale_out*=(100.-double(top_smth_variation))/100.;
+ }
+ }else{
+ if (bot_edge_variation.get_value() != 0)
+ new_pt[Y] += double(bot_edge_variation)-bot_edge_variation.get_value()/2.;
+ if (bot_tgt_variation.get_value() != 0)
+ new_pt[X] += double(bot_tgt_variation)-bot_tgt_variation.get_value()/2.;
+ if (bot_smth_variation.get_value() != 0) {
+ scale_in*=(100.-double(bot_smth_variation))/100.;
+ scale_out*=(100.-double(bot_smth_variation))/100.;
+ }
+ }
+ Point new_hdle_in = new_pt + (pt0-pt1) * (scale_in /2.);
+ Point new_hdle_out = new_pt - (pt0-pt1) * (scale_out/2.);
+
+ if ( fat_output.get_value() ){
+ double scaled_width = double((is_top ? stroke_width_top : stroke_width_bot))/(pt1[X]-pt0[X]);
+ Point hdle_offset = (pt1-pt0)*scaled_width;
+ Point inside = new_pt;
+ Point inside_hdle_in;
+ Point inside_hdle_out;
+ inside[Y]+= double((is_top ? -stroke_width_top : stroke_width_bot));
+ inside_hdle_in = inside + (new_hdle_in -new_pt) + hdle_offset * double((is_top ? front_thickness : back_thickness));
+ inside_hdle_out = inside + (new_hdle_out-new_pt) - hdle_offset * double((is_top ? back_thickness : front_thickness));
+ //TODO: find a good way to handle limit cases (small smthness, large stroke).
+ //if (inside_hdle_in[X] > inside[X]) inside_hdle_in = inside;
+ //if (inside_hdle_out[X] < inside[X]) inside_hdle_out = inside;
+
+ if (is_top){
+ res_comp_top.appendNew<CubicBezier>(last_top_hdle,new_hdle_in,new_pt);
+ res_comp_bot.appendNew<CubicBezier>(last_bot_hdle,inside_hdle_in,inside);
+ last_top_hdle = new_hdle_out;
+ last_bot_hdle = inside_hdle_out;
+ }else{
+ res_comp_top.appendNew<CubicBezier>(last_top_hdle,inside_hdle_in,inside);
+ res_comp_bot.appendNew<CubicBezier>(last_bot_hdle,new_hdle_in,new_pt);
+ last_top_hdle = inside_hdle_out;
+ last_bot_hdle = new_hdle_out;
+ }
+ }else{
+ res_comp.appendNew<CubicBezier>(last_hdle,new_hdle_in,new_pt);
+ }
+
+ last_hdle = new_hdle_out;
+ i+=2;
+ is_top = !is_top;
+ }
+ if ( i<linearSnake[comp].size() )
+ if ( fat_output.get_value() ){
+ res_comp_top.appendNew<CubicBezier>(last_top_hdle,linearSnake[comp][i],linearSnake[comp][i]);
+ res_comp_bot.appendNew<CubicBezier>(last_bot_hdle,linearSnake[comp][i],linearSnake[comp][i]);
+ }else{
+ res_comp.appendNew<CubicBezier>(last_hdle,linearSnake[comp][i],linearSnake[comp][i]);
+ }
+ if ( fat_output.get_value() ){
+ res_comp = res_comp_bot;
+ res_comp.append(res_comp_top.reverse(),Geom::Path::STITCH_DISCONTINUOUS);
+ }
+ result.concat(res_comp.toPwSb());
+ }
+ }
+ return result;
+}
+
+void
+LPEHatches::doBeforeEffect (SPLPEItem */*lpeitem*/)
+{
+ using namespace Geom;
+ top_edge_variation.resetRandomizer();
+ bot_edge_variation.resetRandomizer();
+ top_tgt_variation.resetRandomizer();
+ bot_tgt_variation.resetRandomizer();
+ top_smth_variation.resetRandomizer();
+ bot_smth_variation.resetRandomizer();
+ dist_rdm.resetRandomizer();
+
+ //original_bbox(lpeitem);
+}
+
+
+void
+LPEHatches::resetDefaults(SPItem * item)
+{
+ Geom::OptRect bbox = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX);
+ Geom::Point origin(0.,0.);
+ Geom::Point vector(50.,0.);
+ if (bbox) {
+ origin = bbox->midpoint();
+ vector = Geom::Point((*bbox)[X].extent()/4, 0.);
+ top_edge_variation.param_set_value( (*bbox)[Y].extent()/10, 0 );
+ bot_edge_variation.param_set_value( (*bbox)[Y].extent()/10, 0 );
+ }
+ direction.set_and_write_new_values(origin, vector);
+ bender.param_set_and_write_new_value( origin + Geom::Point(5,0) );
+ hatch_dist = Geom::L2(vector)/5;
+}
+
+
+} //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/lpe-hatches.h b/src/live_effects/lpe-hatches.h new file mode 100644 index 000000000..029847186 --- /dev/null +++ b/src/live_effects/lpe-hatches.h @@ -0,0 +1,77 @@ +#ifndef INKSCAPE_LPE_HATCHES_H
+#define INKSCAPE_LPE_HATCHES_H
+
+/** \file
+ * Implementation of the curve stitch effect, see lpe-hatches.cpp
+ */
+
+/*
+ * Authors:
+ * JFBarraud
+ *
+ * Copyright (C) JF Barraud 2008.
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/point.h"
+#include "live_effects/parameter/parameter.h"
+#include "live_effects/parameter/bool.h"
+#include "live_effects/parameter/random.h"
+#include "live_effects/parameter/vector.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEHatches : public Effect {
+public:
+ LPEHatches(LivePathEffectObject *lpeobject);
+ virtual ~LPEHatches();
+
+ virtual Geom::Piecewise<Geom::D2<Geom::SBasis> >
+ doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
+
+ virtual void resetDefaults(SPItem * item);
+
+ virtual void doBeforeEffect(SPLPEItem * item);
+
+ std::vector<double>
+ generateLevels(Geom::Interval const &domain);
+
+ std::vector<std::vector<Geom::Point> >
+ linearSnake(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &f);
+
+ Geom::Piecewise<Geom::D2<Geom::SBasis> >
+ smoothSnake(std::vector<std::vector<Geom::Point> > const &linearSnake);
+
+private:
+ double hatch_dist;
+ RandomParam dist_rdm;
+ ScalarParam growth;
+ //topfront,topback,bottomfront,bottomback handle scales.
+ ScalarParam scale_tf, scale_tb, scale_bf, scale_bb;
+
+ RandomParam top_edge_variation;
+ RandomParam bot_edge_variation;
+ RandomParam top_tgt_variation;
+ RandomParam bot_tgt_variation;
+ RandomParam top_smth_variation;
+ RandomParam bot_smth_variation;
+
+ BoolParam fat_output, do_bend;
+ ScalarParam stroke_width_top;
+ ScalarParam stroke_width_bot;
+ ScalarParam front_thickness, back_thickness;
+
+ PointParam bender;
+ VectorParam direction;
+
+ LPEHatches(const LPEHatches&);
+ LPEHatches& operator=(const LPEHatches&);
+};
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif
diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index a4c722acc..b2f1547a9 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -61,8 +61,12 @@ LPEInterpolate::doEffect_path (Geom::PathVector const & path_in) Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_B = path_in[1].toPwSb(); // Transform both paths to (0,0) midpoint, so they can easily be positioned along interpolate_path - pwd2_A -= Geom::bounds_exact(pwd2_A).midpoint(); - pwd2_B -= Geom::bounds_exact(pwd2_B).midpoint(); + if (Geom::OptRect bounds = Geom::bounds_exact(pwd2_A)) { + pwd2_A -= bounds->midpoint(); + } + if (Geom::OptRect bounds = Geom::bounds_exact(pwd2_B)) { + pwd2_B -= bounds->midpoint(); + } // Make sure both paths have the same number of segments and cuts at the same locations pwd2_B.setDomain(pwd2_A.domain()); @@ -99,14 +103,18 @@ LPEInterpolate::resetDefaults(SPItem * item) if ( (pathv.size() < 2) ) return; - Geom::Rect bounds_A = pathv[0].boundsExact(); - Geom::Rect bounds_B = pathv[1].boundsExact(); - - Geom::PathVector traj_pathv; - traj_pathv.push_back( Geom::Path() ); - traj_pathv[0].start( bounds_A.midpoint() ); - traj_pathv[0].appendNew<Geom::LineSegment>( bounds_B.midpoint() ); - trajectory_path.set_new_value( traj_pathv, true ); + Geom::OptRect bounds_A = pathv[0].boundsExact(); + Geom::OptRect bounds_B = pathv[1].boundsExact(); + + if (bounds_A && bounds_B) { + Geom::PathVector traj_pathv; + traj_pathv.push_back( Geom::Path() ); + traj_pathv[0].start( bounds_A->midpoint() ); + traj_pathv[0].appendNew<Geom::LineSegment>( bounds_B->midpoint() ); + trajectory_path.set_new_value( traj_pathv, true ); + } else { + trajectory_path.param_set_and_write_default(); + } } } //namespace LivePathEffect diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 0ff1beccf..df18f8767 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -1,12 +1,10 @@ -#define INKSCAPE_LPE_KNOT_CPP -/** \file - * LPE <knot> implementation +/** @file + * @brief LPE knot effect implementation */ -/* - * Authors: - * JF Barraud -* -* Copyright (C) JF Barraud 2007 <jf.barraud@gmail.com> +/* Authors: + * Jean-Francois Barraud <jf.barraud@gmail.com> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -107,8 +105,9 @@ findShadowedTime(Geom::Path const &patha, return Interval(tmin,tmax); } +// TODO: Fix all this in 2geom!!!! //--------------------------------------------------------------------------- -// a 2Geom work around. +// some 2Geom work around. //--------------------------------------------------------------------------- //Cubic Bezier curves might self intersect; the 2geom code used to miss them. @@ -133,29 +132,36 @@ split_at_horiz_vert_tgt (std::vector<Geom::Path> const & path_in){ return ret; } - -//--------------------------------------------------------------------------- -//LPEKnot specific Crossing Data manipulation. -//--------------------------------------------------------------------------- - -//TODO: Fix this in 2Geom: I think CrossingSets should not contain duplicates. +//TODO: Fix this in 2Geom; I think CrossingSets should not contain duplicates. Geom::CrossingSet crossingSet_remove_double(Geom::CrossingSet const &input){ Geom::CrossingSet result(input.size()); //Yeah, I know, there is a "unique" algorithm for that... + //Note: I'm not sure the duplicates are always consecutive!! (can be first and last, I think) + //Note: I also found crossings c with c.a==c.b and c.ta==c.tb . Is it normal? + //Note: I also found crossings c with c.ta or c.tb not in path[a] or path[b] domain. This is definitely not normal. Geom::Crossing last; for( unsigned i=0; i<input.size(); i++){ for( unsigned j=0; j<input[i].size(); j++){ - if( j==0 || !(input[i][j]==last) ){ - result[i].push_back(input[i][j]); - last = input[i][j]; - }else{ - g_warning("Duplicate found in a Geom::CrossingSet!"); + bool dup = false; + for ( unsigned k=0; k<result[i].size(); k++){ + if ( input[i][j]==result[i][k] ){ + dup = true; + g_warning("Duplicate found in a Geom::CrossingSet!"); + break; + } + } + if (!dup) { + result[i].push_back( input[i][j] ); } } } return result; } +//--------------------------------------------------------------------------- +//LPEKnot specific Crossing Data manipulation. +//--------------------------------------------------------------------------- + //TODO: evaluate how usefull/lpeknot specific that is. Worth being moved to 2geom? (I doubt it) namespace LPEKnotNS { @@ -173,15 +179,21 @@ namespace LPEKnotNS { CrossingPoints::CrossingPoints(Geom::CrossingSet const &input, std::vector<Geom::Path> const &path) : std::vector<CrossingPoint>() { using namespace Geom; -// g_print("JF>\nCrossing set content:\n"); + //g_print("DBG>\nCrossing set content:\n"); for( unsigned i=0; i<input.size(); i++){ Crossings i_crossings = input[i]; for( unsigned n=0; n<i_crossings.size(); n++ ){ Crossing c = i_crossings[n]; -// g_print("JF> (%u,%u) at times (%f,%f) ----->",c.a,c.b,c.ta,c.tb); + //g_print("DBG> [%u,%u]:(%u,%u) at times (%f,%f) ----->",i,n,c.a,c.b,c.ta,c.tb); unsigned j = c.getOther(i); - if (i<j || (i==j && c.ta<c.tb) ){ + if (i<j || (i==j && c.ta<=c.tb) ){//FIXME: equality should not happen, but does happen. CrossingPoint cp; + double ti = c.getTime(i); + //FIXME: times in crossing are sometimes out of range!! + //if (0<ti || ti > 1)g_print("oops! -->"); + if (ti > 1) ti=1; + if (ti < 0) ti=0; + cp.pt = path[i].pointAt(c.getTime(i)); cp.i = i; cp.j = j; @@ -189,7 +201,7 @@ CrossingPoints::CrossingPoints(Geom::CrossingSet const &input, std::vector<Geom: Crossing c_bar = c; if (i==j){ c_bar.a = c.b; - c_bar.b = c.a; + c_bar.b = c.a; c_bar.ta = c.tb; c_bar.tb = c.ta; c_bar.dir = !c.dir; @@ -197,24 +209,37 @@ CrossingPoints::CrossingPoints(Geom::CrossingSet const &input, std::vector<Geom: cp.nj = std::find(input[j].begin(),input[j].end(),c_bar)-input[j].begin(); cp.sign = 1; push_back(cp); -// g_print("i=%u, ni=%u, j=%u, nj=%u\n",cp.i,cp.ni,cp.j,cp.nj); - } - else{ -// g_print("\n"); + //g_print("i=%u, ni=%u, j=%u, nj=%u\n",cp.i,cp.ni,cp.j,cp.nj); + }/* + else{ + //debug purpose only: + //This crossing is already registered in output. Just make sure it has a "mirror". + g_print("deja trouve?"); + get(i,n); bool found = false; for( unsigned ii=0; ii<input.size(); ii++){ Crossings ii_crossings = input[ii]; for( unsigned nn=0; nn<ii_crossings.size(); nn++ ){ Crossing cc = ii_crossings[nn]; if (cc.b==c.a && cc.a==c.b && cc.ta==c.tb && cc.tb==c.ta) found = true; + if ( (ii!=i || nn!=n) && + ( (cc.b==c.a && cc.a==c.b && cc.ta==c.tb && cc.tb==c.ta) || + (cc.a==c.a && cc.b==c.b && cc.ta==c.ta && cc.tb==c.tb) + ) ) found = true; } } - if (!found) { - throw std::exception(); - } + assert( found ); + g_print(" oui!\n"); } + */ } } + + //g_print("CrossingPoints reslut:\n"); + //for (unsigned k=0; k<size(); k++){ + // g_print("cpts[%u]: i=%u, ni=%u, j=%u, nj=%u\n",k,(*this)[k].i,(*this)[k].ni,(*this)[k].j,(*this)[k].nj); + //} + } CrossingPoints::CrossingPoints(std::vector<double> const &input) : std::vector<CrossingPoint>() @@ -386,19 +411,8 @@ LPEKnot::doEffect_path (std::vector<Geom::Path> const &input_path) CrossingSet crossingTable = crossings_among(path_in); - for(unsigned i=0;i<crossingTable.size();i++){ - for(unsigned j=0;j<crossingTable[i].size();j++){ -// g_print("JF>avant: %u,%u,%f,%f\n",crossingTable[i][j].a, crossingTable[i][j].b, crossingTable[i][j].ta, crossingTable[i][j].tb); - } - } crossingTable = crossingSet_remove_double(crossingTable); - for(unsigned i=0;i<crossingTable.size();i++){ - for(unsigned j=0;j<crossingTable[i].size();j++){ -// g_print("JF>apres: %u,%u,%f,%f\n",crossingTable[i][j].a, crossingTable[i][j].b, crossingTable[i][j].ta, crossingTable[i][j].tb); - } - } - crossing_points = LPEKnotNS::CrossingPoints(crossingTable, path_in); crossing_points.inherit_signs(old_crdata); crossing_points_vector.param_set_and_write_new_value(crossing_points.to_vector()); @@ -522,8 +536,8 @@ KnotHolderEntityCrossingSwitcher::knot_click(guint state) /* ######################## */ -} //namespace LivePathEffect (setq default-directory "c:/Documents And Settings/jf/Mes Documents/InkscapeSVN") -} /* namespace Inkscape */ +} // namespace LivePathEffect +} // namespace Inkscape /* Local Variables: @@ -534,4 +548,4 @@ KnotHolderEntityCrossingSwitcher::knot_click(guint state) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-knot.h b/src/live_effects/lpe-knot.h index 4c98ccd55..cbd33466d 100644 --- a/src/live_effects/lpe-knot.h +++ b/src/live_effects/lpe-knot.h @@ -1,22 +1,21 @@ -#ifndef INKSCAPE_LPE_KNOT_H -#define INKSCAPE_LPE_KNOT_H - /** \file - * LPE <knot> implementation, see lpe-knot.cpp. + * LPE knot effect implementation, see lpe-knot.cpp. */ - -/* - * Authors: - * JFB, but derived from Johan Engelen! -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Jean-Francois Barraud <jf.barraud@gmail.com> + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) Johan Engelen 2007 * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef INKSCAPE_LPE_KNOT_H +#define INKSCAPE_LPE_KNOT_H + #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" -#include "live_effects/parameter/vector.h" +#include "live_effects/parameter/array.h" #include "live_effects/parameter/path.h" #include "2geom/crossing.h" @@ -70,7 +69,7 @@ private: // add the parameters for your effect here: ScalarParam interruption_width; ScalarParam switcher_size; - VectorParam<double> crossing_points_vector; + ArrayParam<double> crossing_points_vector; LPEKnotNS::CrossingPoints crossing_points; diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 0e5011e51..954a01029 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -66,7 +66,8 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : normal_offset(_("Normal offset"), "", "normal_offset", &wr, this, 0), tang_offset(_("Tangential offset"), "", "tang_offset", &wr, this, 0), prop_units(_("Offsets in unit of pattern size"), _("Spacing, tangential and normal offset are expressed as a ratio of width/height"), "prop_units", &wr, this, false), - vertical_pattern(_("Pattern is vertical"), _("Rotate pattern 90 deg before applying"), "vertical_pattern", &wr, this, false) + vertical_pattern(_("Pattern is vertical"), _("Rotate pattern 90 deg before applying"), "vertical_pattern", &wr, this, false), + fuse_tolerance(_("Fuse nearby ends"), "Fuse ends closer than this number. 0 means don't fuse.", "fuse_tolerance", &wr, this, 0) { registerParameter( dynamic_cast<Parameter *>(&pattern) ); registerParameter( dynamic_cast<Parameter *>(©type) ); @@ -77,6 +78,7 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&tang_offset) ); registerParameter( dynamic_cast<Parameter *>(&prop_units) ); registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) ); + registerParameter( dynamic_cast<Parameter *>(&fuse_tolerance) ); prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); @@ -94,105 +96,122 @@ LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > con /* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */ Piecewise<D2<SBasis> > output; + std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > pre_output; PAPCopyType type = copytype.get_value(); D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(pattern.get_pwd2()); Piecewise<SBasis> x0 = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]); Piecewise<SBasis> y0 = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]); - Interval pattBndsX = bounds_exact(x0); - x0 -= pattBndsX.min(); - Interval pattBndsY = bounds_exact(y0); - y0 -= pattBndsY.middle(); - - double xspace = spacing; - double noffset = normal_offset; - double toffset = tang_offset; - if (prop_units.get_value()){ - xspace *= pattBndsX.extent(); - noffset *= pattBndsY.extent(); - toffset *= pattBndsX.extent(); - } + OptInterval pattBndsX = bounds_exact(x0); + OptInterval pattBndsY = bounds_exact(y0); + if (pattBndsX && pattBndsY) { + x0 -= pattBndsX->min(); + y0 -= pattBndsY->middle(); + + double xspace = spacing; + double noffset = normal_offset; + double toffset = tang_offset; + if (prop_units.get_value() && pattBndsY){ + xspace *= pattBndsX->extent(); + noffset *= pattBndsY->extent(); + toffset *= pattBndsX->extent(); + } - //Prevent more than 90% overlap... - if (xspace < -pattBndsX.extent()*.9) { - xspace = -pattBndsX.extent()*.9; - } - //TODO: dynamical update of parameter ranges? - //if (prop_units.get_value()){ - // spacing.param_set_range(-.9, NR_HUGE); - // }else{ - // spacing.param_set_range(-pattBndsX.extent()*.9, NR_HUGE); - // } - - y0+=noffset; - - std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > paths_in; - paths_in = split_at_discontinuities(pwd2_in); - - for (unsigned idx = 0; idx < paths_in.size(); idx++){ - Geom::Piecewise<Geom::D2<Geom::SBasis> > path_i = paths_in[idx]; - Piecewise<SBasis> x = x0; - Piecewise<SBasis> y = y0; - Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(path_i,2,.1); - uskeleton = remove_short_cuts(uskeleton,.01); - Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton)); - n = force_continuity(remove_short_cuts(n,.1)); - - int nbCopies = 0; - double scaling = 1; - switch(type) { - case PAPCT_REPEATED: - nbCopies = static_cast<int>(floor((uskeleton.domain().extent() - toffset + xspace)/(pattBndsX.extent()+xspace))); - pattBndsX = Interval(pattBndsX.min(),pattBndsX.max()+xspace); - break; - - case PAPCT_SINGLE: - nbCopies = (toffset + pattBndsX.extent() < uskeleton.domain().extent()) ? 1 : 0; - break; - - case PAPCT_SINGLE_STRETCHED: - nbCopies = 1; - scaling = (uskeleton.domain().extent() - toffset)/pattBndsX.extent(); - break; - - case PAPCT_REPEATED_STRETCHED: - // if uskeleton is closed: - if(path_i.segs.front().at0() == path_i.segs.back().at1()){ - nbCopies = static_cast<int>(std::floor((uskeleton.domain().extent() - toffset)/(pattBndsX.extent()+xspace))); - pattBndsX = Interval(pattBndsX.min(),pattBndsX.max()+xspace); - scaling = (uskeleton.domain().extent() - toffset)/(((double)nbCopies)*pattBndsX.extent()); - // if not closed: no space at the end + //Prevent more than 90% overlap... + if (xspace < -pattBndsX->extent()*.9) { + xspace = -pattBndsX->extent()*.9; + } + //TODO: dynamical update of parameter ranges? + //if (prop_units.get_value()){ + // spacing.param_set_range(-.9, NR_HUGE); + // }else{ + // spacing.param_set_range(-pattBndsX.extent()*.9, NR_HUGE); + // } + + y0+=noffset; + + std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > paths_in; + paths_in = split_at_discontinuities(pwd2_in); + + for (unsigned idx = 0; idx < paths_in.size(); idx++){ + Geom::Piecewise<Geom::D2<Geom::SBasis> > path_i = paths_in[idx]; + Piecewise<SBasis> x = x0; + Piecewise<SBasis> y = y0; + Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(path_i,2,.1); + uskeleton = remove_short_cuts(uskeleton,.01); + Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton)); + n = force_continuity(remove_short_cuts(n,.1)); + + int nbCopies = 0; + double scaling = 1; + switch(type) { + case PAPCT_REPEATED: + nbCopies = static_cast<int>(floor((uskeleton.domain().extent() - toffset + xspace)/(pattBndsX->extent()+xspace))); + pattBndsX = Interval(pattBndsX->min(),pattBndsX->max()+xspace); + break; + + case PAPCT_SINGLE: + nbCopies = (toffset + pattBndsX->extent() < uskeleton.domain().extent()) ? 1 : 0; + break; + + case PAPCT_SINGLE_STRETCHED: + nbCopies = 1; + scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); + break; + + case PAPCT_REPEATED_STRETCHED: + // if uskeleton is closed: + if(path_i.segs.front().at0() == path_i.segs.back().at1()){ + nbCopies = static_cast<int>(std::floor((uskeleton.domain().extent() - toffset)/(pattBndsX->extent()+xspace))); + pattBndsX = Interval(pattBndsX->min(),pattBndsX->max()+xspace); + scaling = (uskeleton.domain().extent() - toffset)/(((double)nbCopies)*pattBndsX->extent()); + // if not closed: no space at the end + }else{ + nbCopies = static_cast<int>(std::floor((uskeleton.domain().extent() - toffset + xspace)/(pattBndsX->extent()+xspace))); + pattBndsX = Interval(pattBndsX->min(),pattBndsX->max()+xspace); + scaling = (uskeleton.domain().extent() - toffset)/(((double)nbCopies)*pattBndsX->extent() - xspace); + } + break; + + default: + return pwd2_in; + }; + + double pattWidth = pattBndsX->extent() * scaling; + + if (scaling != 1.0) { + x*=scaling; + } + if ( scale_y_rel.get_value() ) { + y*=(scaling*prop_scale); + } else { + if (prop_scale != 1.0) y *= prop_scale; + } + x += toffset; + + double offs = 0; + for (int i=0; i<nbCopies; i++){ + if (fuse_tolerance > 0){ + Geom::Piecewise<Geom::D2<Geom::SBasis> > output_piece = compose(uskeleton,x+offs)+y*compose(n,x+offs); + std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > splited_output_piece = split_at_discontinuities(output_piece); + pre_output.insert(pre_output.end(), splited_output_piece.begin(), splited_output_piece.end() ); }else{ - nbCopies = static_cast<int>(std::floor((uskeleton.domain().extent() - toffset + xspace)/(pattBndsX.extent()+xspace))); - pattBndsX = Interval(pattBndsX.min(),pattBndsX.max()+xspace); - scaling = (uskeleton.domain().extent() - toffset)/(((double)nbCopies)*pattBndsX.extent() - xspace); + output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs)); } - break; - - default: - return pwd2_in; - }; - - double pattWidth = pattBndsX.extent() * scaling; - - if (scaling != 1.0) { - x*=scaling; - } - if ( scale_y_rel.get_value() ) { - y*=(scaling*prop_scale); - } else { - if (prop_scale != 1.0) y *= prop_scale; + offs+=pattWidth; + } } - x += toffset; - - double offs = 0; - for (int i=0; i<nbCopies; i++){ - output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs)); - offs+=pattWidth; + if (fuse_tolerance > 0){ + pre_output = fuse_nearby_ends(pre_output, fuse_tolerance); + for (unsigned i=0; i<pre_output.size(); i++){ + output.concat(pre_output[i]); + } } + return output; + } else { + return pwd2_in; } - return output; } LPEFreehandShape::LPEFreehandShape(LivePathEffectObject *lpeobject) : LPEPatternAlongPath(lpeobject) diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index 5adc049fb..f35f7a5cb 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -42,6 +42,7 @@ private: ScalarParam tang_offset; BoolParam prop_units; BoolParam vertical_pattern; + ScalarParam fuse_tolerance; void on_pattern_pasted(); diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 2eef0cd5b..d5262f33c 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -1,22 +1,11 @@ -#define INKSCAPE_LPE_PERSPECTIVE_PATH_CPP -/** \file - * LPE <perspective_path> implementation, used as an example for a base starting class - * when implementing new LivePathEffects. - * - * In vi, three global search-and-replaces will let you rename everything - * in this and the .h file: - * - * :%s/PERSPECTIVE_PATH/YOURNAME/g - * :%s/PerspectivePath/Yourname/g - * :%s/perspective_path/yourname/g +/** @file + * @brief LPE perspective path effect implementation. */ -/* - * Authors: - * Johan Engelen - * Maximilian Albert +/* Authors: + * Maximilian Albert <maximilian.albert@gmail.com> + * Johan Engelen <j.b.c.engelen@utwente.nl> * - * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> - * Copyright (C) Maximilian Albert 2008 <maximilian.albert@gmail.com> + * Copyright (C) 2007-2008 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -198,4 +187,4 @@ KnotHolderEntityOffset::knot_get() fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index 62589e875..23731f9f7 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -1,19 +1,18 @@ -#ifndef INKSCAPE_LPE_PERSPECTIVE_PATH_H -#define INKSCAPE_LPE_PERSPECTIVE_PATH_H - -/** \file - * LPE <perspective_path> implementation, see lpe-perspective_path.cpp. +/** @file + * @brief LPE perspective path effect implementation */ - -/* - * Authors: - * Johan Engelen -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Maximilian Albert <maximilian.albert@gmail.com> + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef INKSCAPE_LPE_PERSPECTIVE_PATH_H +#define INKSCAPE_LPE_PERSPECTIVE_PATH_H + #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/bool.h" @@ -65,3 +64,14 @@ private: } //namespace Inkscape #endif + +/* + 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/live_effects/lpe-skeleton.cpp b/src/live_effects/lpe-skeleton.cpp index c2ab7be51..fdee68b88 100644 --- a/src/live_effects/lpe-skeleton.cpp +++ b/src/live_effects/lpe-skeleton.cpp @@ -1,7 +1,7 @@ #define INKSCAPE_LPE_SKELETON_CPP /** \file - * LPE <skeleton> implementation, used as an example for a base starting class - * when implementing new LivePathEffects. + * @brief Minimal dummy LPE effect implementation, used as an example for a base + * starting class when implementing new LivePathEffects. * * In vi, three global search-and-replaces will let you rename everything * in this and the .h file: @@ -10,11 +10,10 @@ * :%s/Skeleton/Yourname/g * :%s/skeleton/yourname/g */ -/* - * Authors: - * Johan Engelen +/* Authors: + * Johan Engelen <j.b.c.engelen@utwente.nl> * - * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -84,7 +83,7 @@ LPESkeleton::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd * Define the classes for your knotholder handles here */ -/** +/* namespace Skeleton { class KnotHolderEntityMyHandle : public LPEKnotHolderEntity @@ -97,7 +96,7 @@ public: }; } // namespace Skeleton -**/ +*/ /* ######################## */ @@ -113,4 +112,4 @@ public: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-skeleton.h b/src/live_effects/lpe-skeleton.h index d961ad954..fd9dc0aba 100644 --- a/src/live_effects/lpe-skeleton.h +++ b/src/live_effects/lpe-skeleton.h @@ -1,19 +1,17 @@ -#ifndef INKSCAPE_LPE_SKELETON_H -#define INKSCAPE_LPE_SKELETON_H - -/** \file - * LPE <skeleton> implementation, see lpe-skeleton.cpp. +/** @file + * @brief Minimal LPE effect, see lpe-skeleton.cpp. */ - -/* - * Authors: - * Johan Engelen +/* Authors: + * Johan Engelen <j.b.c.engelen@utwente.nl> * - * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef INKSCAPE_LPE_SKELETON_H +#define INKSCAPE_LPE_SKELETON_H + #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" @@ -65,4 +63,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp index 38957a658..1fe4ba525 100644 --- a/src/live_effects/lpe-sketch.cpp +++ b/src/live_effects/lpe-sketch.cpp @@ -1,12 +1,11 @@ -#define INKSCAPE_LPE_SKETCH_CPP -/** \file - * LPE <sketch> implementation +/** @file + * @brief LPE sketch effect implementation */ -/* - * Authors: - * Johan Engelen -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Jean-Francois Barraud <jf.barraud@gmail.com> + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -189,7 +188,7 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ //----- Approximated Strokes. std::vector<Piecewise<D2<SBasis> > > pieces_in = split_at_discontinuities (pwd2_in); - + //work separately on each component. for (unsigned pieceidx = 0; pieceidx < pieces_in.size(); pieceidx++){ @@ -247,10 +246,11 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ t1 = times[0]; //pick a rdm perturbation, and collect the perturbed piece into output. - Piecewise<D2<SBasis> > pwperturb = computePerturbation(s0,s1); + Piecewise<D2<SBasis> > pwperturb = computePerturbation(s0-0.01,s1+0.01); pwperturb = compose(pwperturb,portion(piecelength,t0,t1)); + output.concat(portion(piece,t0,t1)+pwperturb); - + //step points: s0 = s1 - overlap. //TODO: make sure this has to end? s0 = s1 - strokeoverlap*(1-strokeoverlap_rdm)*(s1-s0); @@ -258,7 +258,6 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ } } - //----- Construction lines. //TODO: choose places according to curvature?. @@ -268,7 +267,9 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ Piecewise<D2<SBasis> > m = pwd2_in; Piecewise<D2<SBasis> > v = derivative(pwd2_in); Piecewise<D2<SBasis> > a = derivative(v); + for (unsigned i=0; i<nbtangents; i++){ + // pick a point where to draw a tangent (s = dist from start along path). double s = total_length * ( i + tgtlength_rdm ) / (nbtangents+1.); std::vector<double> times; @@ -290,6 +291,7 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ } output.concat(Piecewise<D2<SBasis> >(tgt)); } + return output; } @@ -319,4 +321,4 @@ LPESketch::doBeforeEffect (SPLPEItem *lpeitem) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-sketch.h b/src/live_effects/lpe-sketch.h index bca4e2447..4237c2b67 100644 --- a/src/live_effects/lpe-sketch.h +++ b/src/live_effects/lpe-sketch.h @@ -1,19 +1,18 @@ -#ifndef INKSCAPE_LPE_SKETCH_H -#define INKSCAPE_LPE_SKETCH_H - /** \file - * LPE <sketch> implementation, see lpe-sketch.cpp. + * @brief LPE sketch effect implementation, see lpe-sketch.cpp. */ - -/* - * Authors: - * JFB, but derived from Johan Engelen! -* -* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl> +/* Authors: + * Jean-Francois Barraud <jf.barraud@gmail.com> + * Johan Engelen <j.b.c.engelen@utwente.nl> + * + * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef INKSCAPE_LPE_SKETCH_H +#define INKSCAPE_LPE_SKETCH_H + #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/random.h" @@ -59,3 +58,14 @@ private: } //namespace Inkscape #endif + +/* + 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/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 3b1ece2ad..3820b5ba7 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -37,7 +37,7 @@ GroupBBoxEffect::original_bbox(SPLPEItem *lpeitem, bool absolute) transform = Geom::identity(); } - boost::optional<Geom::Rect> bbox = item->getBounds(transform, SPItem::GEOMETRIC_BBOX); + Geom::OptRect bbox = item->getBounds(transform, SPItem::GEOMETRIC_BBOX); if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; diff --git a/src/live_effects/parameter/CMakeLists.txt b/src/live_effects/parameter/CMakeLists.txt index d7775f44d..f93d8910a 100644 --- a/src/live_effects/parameter/CMakeLists.txt +++ b/src/live_effects/parameter/CMakeLists.txt @@ -1,4 +1,5 @@ SET(live_effects_parameter_SRC +array.cpp bool.cpp parameter.cpp path.cpp diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index 869f4a7f4..3832e24cb 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -8,14 +8,14 @@ live_effects/parameter/clean: live_effects_parameter_liblpeparam_a_SOURCES = \ live_effects/parameter/parameter.cpp \ live_effects/parameter/parameter.h \ + live_effects/parameter/array.cpp \ + live_effects/parameter/array.h \ live_effects/parameter/bool.cpp \ live_effects/parameter/bool.h \ live_effects/parameter/random.cpp \ live_effects/parameter/random.h \ live_effects/parameter/point.cpp \ live_effects/parameter/point.h \ - live_effects/parameter/pointparam-knotholder.cpp \ - live_effects/parameter/pointparam-knotholder.h \ live_effects/parameter/enum.h \ live_effects/parameter/path-reference.cpp \ live_effects/parameter/path-reference.h \ diff --git a/src/live_effects/parameter/array.cpp b/src/live_effects/parameter/array.cpp new file mode 100644 index 000000000..c576bedd5 --- /dev/null +++ b/src/live_effects/parameter/array.cpp @@ -0,0 +1,51 @@ +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ARRAY_CPP + +/* + * Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/array.h" + +#include "svg/svg.h" +#include "svg/stringstream.h" + +#include <2geom/coord.h> + +namespace Inkscape { + +namespace LivePathEffect { + +template <> +double +ArrayParam<double>::readsvg(const gchar * str) +{ + double newx = Geom::infinity(); + sp_svg_number_read_d(str, &newx); + return newx; +} + +template <> +float +ArrayParam<float>::readsvg(const gchar * str) +{ + float newx = Geom::infinity(); + sp_svg_number_read_f(str, &newx); + return newx; +} + +} /* 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/array.h b/src/live_effects/parameter/array.h new file mode 100644 index 000000000..4da329c4d --- /dev/null +++ b/src/live_effects/parameter/array.h @@ -0,0 +1,123 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ARRAY_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ARRAY_H + +/* + * Inkscape::LivePathEffectParameters + * +* Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <vector> + +#include <glib/gtypes.h> + +#include <gtkmm/tooltips.h> + +#include "live_effects/parameter/parameter.h" + +#include "svg/svg.h" +#include "svg/stringstream.h" + +namespace Inkscape { + +namespace LivePathEffect { + +template <typename StorageType> +class ArrayParam : public Parameter { +public: + ArrayParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + size_t n = 0 ) + : Parameter(label, tip, key, wr, effect), _vector(n) + { + + } + + virtual ~ArrayParam() { + + }; + + std::vector<StorageType> const & data() const { + return _vector; + } + + virtual Gtk::Widget * param_newWidget(Gtk::Tooltips * /*tooltips*/) { + return NULL; + } + + virtual bool param_readSVGValue(const gchar * strvalue) { + _vector.clear(); + gchar ** strarray = g_strsplit(strvalue, "|", 0); + gchar ** iter = strarray; + while (*iter != NULL) { + _vector.push_back( readsvg(*iter) ); + iter++; + } + g_strfreev (strarray); + return true; + } + + virtual gchar * param_getSVGValue() const { + Inkscape::SVGOStringStream os; + writesvg(os, _vector); + gchar * str = g_strdup(os.str().c_str()); + return str; + } + + void param_setValue(std::vector<StorageType> const &new_vector) { + _vector = new_vector; + } + + void param_set_default() { + param_setValue( std::vector<StorageType>() ); + } + + void param_set_and_write_new_value(std::vector<StorageType> const &new_vector) { + Inkscape::SVGOStringStream os; + writesvg(os, new_vector); + gchar * str = g_strdup(os.str().c_str()); + param_write_to_repr(str); + g_free(str); + } + +private: + ArrayParam(const ArrayParam&); + ArrayParam& operator=(const ArrayParam&); + + std::vector<StorageType> _vector; + + void writesvg(SVGOStringStream &str, std::vector<StorageType> const &vector) const { + for (unsigned int i = 0; i < vector.size(); ++i) { + if (i != 0) { + // separate items with pipe symbol + str << " | "; + } + str << vector[i]; + } + } + + StorageType readsvg(const gchar * str); +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif + +/* + 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/parameter.h b/src/live_effects/parameter/parameter.h index aac3dfa69..71bd5673d 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -60,7 +60,8 @@ public: virtual Glib::ustring * param_getTooltip() { return ¶m_tooltip; }; // overload these for your particular parameter to make it provide knotholder handles or canvas helperpaths - virtual void addKnotHolderEntities(KnotHolder */*knotholder*/, SPDesktop */*desktop*/, SPItem */*item*/) {} + virtual bool providesKnotHolderEntities() { return false; } + virtual void addKnotHolderEntities(KnotHolder */*knotholder*/, SPDesktop */*desktop*/, SPItem */*item*/) {}; virtual void addCanvasIndicators(SPLPEItem */*lpeitem*/, std::vector<Geom::PathVector> &/*hp_vec*/) {}; virtual void param_editOncanvas(SPItem * /*item*/, SPDesktop * /*dt*/) {}; diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 5d541eff8..057cc424b 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -7,7 +7,6 @@ */ #include "live_effects/parameter/point.h" -#include "live_effects/parameter/pointparam-knotholder.h" #include "live_effects/effect.h" #include "svg/svg.h" #include "svg/stringstream.h" diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index ca440c1fc..ec61fcd88 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -49,14 +49,13 @@ public: void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + virtual bool providesKnotHolderEntities() { return true; } virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); private: PointParam(const PointParam&); PointParam& operator=(const PointParam&); - void on_button_click(); - Geom::Point defvalue; SPKnotShapeType knot_shape; diff --git a/src/live_effects/parameter/pointparam-knotholder.cpp b/src/live_effects/parameter/pointparam-knotholder.cpp deleted file mode 100644 index b814f597d..000000000 --- a/src/live_effects/parameter/pointparam-knotholder.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#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 <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, Geom::Point const *p, guint state, PointParamKnotHolder *kh); -static void pointparam_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, PointParamKnotHolder *kh); - -PointParamKnotHolder::PointParamKnotHolder(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item) -{ - if (!desktop || !item || !SP_IS_ITEM(item)) { - g_print ("Error! Throw an exception, please!\n"); - } - - this->desktop = desktop; - this->item = item; - this->lpeobject = LIVEPATHEFFECT(lpeobject); - g_object_ref(G_OBJECT(item)); - g_object_ref(G_OBJECT(lpeobject)); - - this->released = NULL; - - this->repr = lpeobject->repr; - this->repr_key = key; - - this->local_change = FALSE; -} - -PointParamKnotHolder::~PointParamKnotHolder() -{ - g_object_unref(G_OBJECT(this->item)); - g_object_unref(G_OBJECT(this->lpeobject)); -} - -class KnotHolderEntityPointParam : public LPEKnotHolderEntity { -public: - virtual Geom::Point knot_get(); - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); -}; - -Geom::Point -KnotHolderEntityPointParam::knot_get() { - return Geom::Point(0,0); -} - -void -KnotHolderEntityPointParam::knot_set(Geom::Point const &/*p*/, Geom::Point const &/*origin*/, guint /*state*/) { -} - -void -PointParamKnotHolder::add_knot ( - Geom::Point & p, -// TODO: check if knot_click being ignored is bad: - PointParamKnotHolderClickedFunc /*knot_click*/, - SPKnotShapeType shape, - SPKnotModeType mode, - guint32 color, - const gchar *tip ) -{ - /* create new SPKnotHolderEntry */ - KnotHolderEntity *e = new KnotHolderEntityPointParam(); - e->create(this->desktop, this->item, this, tip, shape, mode, color); - - entity.push_back(e); - - // Move to current point. - Geom::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*/, Geom::Point const *p, guint /*state*/, PointParamKnotHolder *kh) -{ - Geom::Matrix const i2d(sp_item_i2d_affine(kh->getItem())); - Geom::Point pos = (*p) * i2d.inverse(); - - Inkscape::SVGOStringStream os; - os << pos; - - // note: get_lpe() will always return a valid pointer? - kh->lpeobject->get_lpe()->setParameter(kh->repr_key, os.str().c_str()); -} - -static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh) -{ - Geom::Matrix const i2d(sp_item_i2d_affine(kh->getItem())); - Geom::Point pos = sp_knot_position(knot) * i2d.inverse(); - - Inkscape::SVGOStringStream os; - os << pos; - - 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/live_effects/parameter/pointparam-knotholder.h b/src/live_effects/parameter/pointparam-knotholder.h deleted file mode 100644 index f6dfdead5..000000000 --- a/src/live_effects/parameter/pointparam-knotholder.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_H -#define INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_H - -/* - * PointParamKnotHolder - Hold SPKnot list and manage signals for LPE PointParam - * - * Author: - * Johan Engelen <goejendaagh@zonnet.nl> - * - * Copyright (C) 2008 Johan Engelen - * - * Released under GNU GPL - * - */ - -#include "knotholder.h" -#include <glib/gtypes.h> -#include "knot-enums.h" -#include "forward.h" -#include "libnr/nr-forward.h" -#include <2geom/point.h> -#include "live_effects/lpeobject.h" - -namespace Inkscape { -namespace XML { -class Node; -} - - - -typedef void (* PointParamKnotHolderSetFunc) (SPItem *item, Geom::Point const &p, Geom::Point const &origin, guint state); -typedef Geom::Point (* PointParamKnotHolderGetFunc) (SPItem *item); -typedef void (* PointParamKnotHolderClickedFunc) (SPItem *item, guint state); - -class PointParamKnotHolder : public KnotHolder { -public: - PointParamKnotHolder(SPDesktop *desktop, SPObject *lpeobject, const gchar * key, SPItem *item); - ~PointParamKnotHolder(); - - LivePathEffectObject * lpeobject; - Inkscape::XML::Node * repr; - const gchar * repr_key; - - void add_knot ( Geom::Point & p, - PointParamKnotHolderClickedFunc knot_click, - SPKnotShapeType shape, - SPKnotModeType mode, - guint32 color, - const gchar *tip ); -}; - -} // namespace Inkscape - - -#endif /* INKSCAPE_LPE_POINTPARAM_KNOTHOLDER_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:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/parameter/vector.cpp b/src/live_effects/parameter/vector.cpp index 90d9ebff9..9a68334fd 100644 --- a/src/live_effects/parameter/vector.cpp +++ b/src/live_effects/parameter/vector.cpp @@ -7,32 +7,190 @@ */ #include "live_effects/parameter/vector.h" - +#include "sp-lpe-item.h" +#include "knotholder.h" #include "svg/svg.h" #include "svg/stringstream.h" +#include <gtkmm.h> -#include <2geom/coord.h> +// needed for on-canvas editting: +class SPDesktop; namespace Inkscape { namespace LivePathEffect { -template <> -double -VectorParam<double>::readsvg(const gchar * str) +VectorParam::VectorParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, Geom::Point default_vector) + : Parameter(label, tip, key, wr, effect), + defvalue(default_vector), + origin(0.,0.), + vector(default_vector) +{ + vec_knot_shape = SP_KNOT_SHAPE_DIAMOND; + vec_knot_mode = SP_KNOT_MODE_XOR; + vec_knot_color = 0xffffb500; + ori_knot_shape = SP_KNOT_SHAPE_CIRCLE; + ori_knot_mode = SP_KNOT_MODE_XOR; + ori_knot_color = 0xffffb500; +} + +VectorParam::~VectorParam() +{ + +} + +void +VectorParam::param_set_default() +{ + setOrigin(Geom::Point(0.,0.)); + setVector(defvalue); +} + +bool +VectorParam::param_readSVGValue(const gchar * strvalue) +{ + gchar ** strarray = g_strsplit(strvalue, ",", 4); + double val[4]; + unsigned int i = 0; + while (strarray[i] && i < 4) { + if (sp_svg_number_read_d(strarray[i], &val[i]) != 0) { + i++; + } else { + break; + } + } + g_strfreev (strarray); + if (i == 4) { + setOrigin( Geom::Point(val[0], val[1]) ); + setVector( Geom::Point(val[2], val[3]) ); + return true; + } + return false; +} + +gchar * +VectorParam::param_getSVGValue() const +{ + Inkscape::SVGOStringStream os; + os << origin << " , " << vector; + gchar * str = g_strdup(os.str().c_str()); + return str; +} + +Gtk::Widget * +VectorParam::param_newWidget(Gtk::Tooltips * /*tooltips*/) +{ +/* + Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() ) ); + // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Geom::Matrix transf = desktop->doc2dt(); + pointwdg->setTransform(transf); + pointwdg->setValue( *this ); + pointwdg->clearProgrammatically(); + pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); + + Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); + static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true); + static_cast<Gtk::HBox*>(hbox)->show_all_children(); + + return dynamic_cast<Gtk::Widget *> (hbox); + */ return NULL; +} + +void +VectorParam::set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector) +{ + setValues(new_origin, new_vector); + gchar * str = param_getSVGValue(); + param_write_to_repr(str); + g_free(str); +} + +void +VectorParam::param_transform_multiply(Geom::Matrix const& postmul, bool /*set*/) +{ + set_and_write_new_values( origin * postmul, vector * postmul ); +} + + +void +VectorParam::set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) { - double newx = Geom::infinity(); - sp_svg_number_read_d(str, &newx); - return newx; + vec_knot_shape = shape; + vec_knot_mode = mode; + vec_knot_color = color; } -template <> -float -VectorParam<float>::readsvg(const gchar * str) +void +VectorParam::set_origin_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) { - float newx = Geom::infinity(); - sp_svg_number_read_f(str, &newx); - return newx; + ori_knot_shape = shape; + ori_knot_mode = mode; + ori_knot_color = color; +} + +class VectorParamKnotHolderEntity_Origin : public LPEKnotHolderEntity { +public: + VectorParamKnotHolderEntity_Origin(VectorParam *p) : param(p) { } + virtual ~VectorParamKnotHolderEntity_Origin() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) { + Geom::Point const s = snap_knot_position(p); + param->setOrigin(s); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + }; + virtual Geom::Point knot_get(){ + return param->origin; + }; + virtual void knot_click(guint /*state*/){ + g_print ("This is the origin handle associated to parameter '%s'\n", param->param_key.c_str()); + }; + +private: + VectorParam *param; +}; + +class VectorParamKnotHolderEntity_Vector : public LPEKnotHolderEntity { +public: + VectorParamKnotHolderEntity_Vector(VectorParam *p) : param(p) { } + virtual ~VectorParamKnotHolderEntity_Vector() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { + Geom::Point const s = p - param->origin; + /// @todo implement angle snapping when holding CTRL + param->setVector(s); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + }; + virtual Geom::Point knot_get(){ + return param->origin + param->vector; + }; + virtual void knot_click(guint /*state*/){ + g_print ("This is the vector handle associated to parameter '%s'\n", param->param_key.c_str()); + }; + +private: + VectorParam *param; +}; + +void +VectorParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + VectorParamKnotHolderEntity_Origin *origin_e = new VectorParamKnotHolderEntity_Origin(this); + origin_e->create(desktop, item, knotholder, handleTip(), ori_knot_shape, ori_knot_mode, ori_knot_color); + knotholder->add(origin_e); + + VectorParamKnotHolderEntity_Vector *vector_e = new VectorParamKnotHolderEntity_Vector(this); + vector_e->create(desktop, item, knotholder, handleTip(), vec_knot_shape, vec_knot_mode, vec_knot_color); + knotholder->add(vector_e); } } /* namespace LivePathEffect */ diff --git a/src/live_effects/parameter/vector.h b/src/live_effects/parameter/vector.h index 0b65fea14..a4c29d317 100644 --- a/src/live_effects/parameter/vector.h +++ b/src/live_effects/parameter/vector.h @@ -4,27 +4,25 @@ /* * Inkscape::LivePathEffectParameters * -* Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> + * Copyright (C) Johan Engelen 2008 <j.b.c.engelen@utwente.nl> * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <vector> - #include <glib/gtypes.h> +#include <2geom/point.h> #include <gtkmm/tooltips.h> #include "live_effects/parameter/parameter.h" -#include "svg/svg.h" -#include "svg/stringstream.h" +#include "knot-holder-entity.h" namespace Inkscape { namespace LivePathEffect { -template <typename StorageType> + class VectorParam : public Parameter { public: VectorParam( const Glib::ustring& label, @@ -32,76 +30,51 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - size_t n = 0 ) - : Parameter(label, tip, key, wr, effect), _vector(n) - { - - } - - virtual ~VectorParam() { - - }; - - std::vector<StorageType> const & data() const { - return _vector; - } - - virtual Gtk::Widget * param_newWidget(Gtk::Tooltips * /*tooltips*/) { - return NULL; - } - - virtual bool param_readSVGValue(const gchar * strvalue) { - _vector.clear(); - gchar ** strarray = g_strsplit(strvalue, "|", 0); - gchar ** iter = strarray; - while (*iter != NULL) { - _vector.push_back( readsvg(*iter) ); - iter++; - } - g_strfreev (strarray); - return true; - } - - virtual gchar * param_getSVGValue() const { - Inkscape::SVGOStringStream os; - writesvg(os, _vector); - gchar * str = g_strdup(os.str().c_str()); - return str; - } - - void param_setValue(std::vector<StorageType> const &new_vector) { - _vector = new_vector; - } - - void param_set_default() { - param_setValue( std::vector<StorageType>() ); - } - - void param_set_and_write_new_value(std::vector<StorageType> const &new_vector) { - Inkscape::SVGOStringStream os; - writesvg(os, new_vector); - gchar * str = g_strdup(os.str().c_str()); - param_write_to_repr(str); - g_free(str); - } + Geom::Point default_vector = Geom::Point(1,0) ); + virtual ~VectorParam(); + + virtual Gtk::Widget * param_newWidget(Gtk::Tooltips * tooltips); + inline const gchar *handleTip() const { return param_tooltip.c_str(); } + + virtual bool param_readSVGValue(const gchar * strvalue); + virtual gchar * param_getSVGValue() const; + + Geom::Point getVector() const { return vector; }; + Geom::Point getOrigin() const { return origin; }; + void setValues(Geom::Point const &new_origin, Geom::Point const &new_vector) { setVector(new_vector); setOrigin(new_origin); }; + void setVector(Geom::Point const &new_vector) { vector = new_vector; }; + void setOrigin(Geom::Point const &new_origin) { origin = new_origin; }; + virtual void param_set_default(); + + void set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector); + + virtual void param_transform_multiply(Geom::Matrix const &postmul, bool set); + + void set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + void set_origin_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + + virtual bool providesKnotHolderEntities() { return true; } + virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); private: VectorParam(const VectorParam&); VectorParam& operator=(const VectorParam&); - std::vector<StorageType> _vector; + Geom::Point defvalue; - void writesvg(SVGOStringStream &str, std::vector<StorageType> const &vector) const { - for (unsigned int i = 0; i < vector.size(); ++i) { - if (i != 0) { - // separate items with pipe symbol - str << " | "; - } - str << vector[i]; - } - } + Geom::Point origin; + Geom::Point vector; - StorageType readsvg(const gchar * str); + /// The looks of the vector and origin knots oncanvas + SPKnotShapeType vec_knot_shape; + SPKnotModeType vec_knot_mode; + guint32 vec_knot_color; + SPKnotShapeType ori_knot_shape; + SPKnotModeType ori_knot_mode; + guint32 ori_knot_color; + + friend class VectorParamKnotHolderEntity_Origin; + friend class VectorParamKnotHolderEntity_Vector; }; @@ -110,14 +83,3 @@ private: } //namespace Inkscape #endif - -/* - 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/lpe-tool-context.cpp b/src/lpe-tool-context.cpp index 8439f7086..5c6575cca 100644 --- a/src/lpe-tool-context.cpp +++ b/src/lpe-tool-context.cpp @@ -203,9 +203,10 @@ sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpointer da static void sp_lpetool_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val) { - // FIXME: how to set this correcly? the value from preferences-skeleton.h doesn't seem to get - // read (it wants to set drag = 1) - // lpetool_parent_class->set(ec, key, "drag"); + if (val->getEntryName() == "mode") { + Inkscape::Preferences::get()->setString("/tools/geometric/mode", "drag"); + SP_PEN_CONTEXT(ec)->mode = SP_PEN_CONTEXT_MODE_DRAG; + } /* //pass on up to parent class to handle common attributes. diff --git a/src/main.cpp b/src/main.cpp index 5e1e6f64b..af896d7d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,6 +82,7 @@ #include "debug/log-display-config.h" #include "helper/png-write.h" +#include "helper/geom.h" #include <extension/extension.h> #include <extension/system.h> @@ -1056,7 +1057,7 @@ do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gch SPItem *item = ((SPItem *) o); // "true" SVG bbox for scripting - boost::optional<Geom::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect area = item->getBounds(sp_item_i2doc_affine(item)); if (area) { Inkscape::SVGOStringStream os; if (extent) { @@ -1089,7 +1090,7 @@ do_query_all_recurse (SPObject *o) { SPItem *item = ((SPItem *) o); if (o->id && SP_IS_ITEM(item)) { - boost::optional<Geom::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect area = item->getBounds(sp_item_i2doc_affine(item)); if (area) { Inkscape::SVGOStringStream os; os << o->id; @@ -1121,7 +1122,7 @@ sp_do_export_png(SPDocument *doc) GSList *items = NULL; - NRRect area; + Geom::Rect area; if (sp_export_id || sp_export_area_drawing) { SPObject *o = NULL; @@ -1181,10 +1182,10 @@ sp_do_export_png(SPDocument *doc) // write object bbox to area sp_document_ensure_up_to_date (doc); - boost::optional<Geom::Rect> areaMaybe; + Geom::OptRect areaMaybe; sp_item_invoke_bbox((SPItem *) o_area, areaMaybe, sp_item_i2r_affine((SPItem *) o_area), TRUE); if (areaMaybe) { - area = NRRect(areaMaybe); + area = *areaMaybe; } else { g_warning("Unable to determine a valid bounding box. Nothing exported."); return; @@ -1197,21 +1198,17 @@ sp_do_export_png(SPDocument *doc) if (sp_export_area) { /* Try to parse area (given in SVG pixels) */ - if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) { + gdouble x0,y0,x1,y1; + if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &x0, &y0, &x1, &y1) == 4) { g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area); return; } - if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) { - g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area); - return; - } + area = Geom::Rect(Geom::Interval(x0,x1), Geom::Interval(y0,y1)); } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) { /* Export the whole canvas */ sp_document_ensure_up_to_date (doc); - area.x0 = SP_ROOT(doc->root)->x.computed; - area.y0 = SP_ROOT(doc->root)->y.computed; - area.x1 = area.x0 + sp_document_width (doc); - area.y1 = area.y0 + sp_document_height (doc); + Geom::Point origin (SP_ROOT(doc->root)->x.computed, SP_ROOT(doc->root)->y.computed); + area = Geom::Rect(origin, origin + sp_document_dimensions(doc)); } // set filename and dpi from options, if not yet set from the hints @@ -1233,10 +1230,7 @@ sp_do_export_png(SPDocument *doc) } if (sp_export_area_snap) { - area.x0 = std::floor (area.x0); - area.y0 = std::floor (area.y0); - area.x1 = std::ceil (area.x1); - area.y1 = std::ceil (area.y1); + round_rectangle_outwards(area); } // default dpi @@ -1254,7 +1248,7 @@ sp_do_export_png(SPDocument *doc) g_warning("Export width %lu out of range (1 - %lu). Nothing exported.", width, (unsigned long int)PNG_UINT_31_MAX); return; } - dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0); + dpi = (gdouble) width * PX_PER_IN / area.width(); } if (sp_export_height) { @@ -1264,15 +1258,15 @@ sp_do_export_png(SPDocument *doc) g_warning("Export height %lu out of range (1 - %lu). Nothing exported.", height, (unsigned long int)PNG_UINT_31_MAX); return; } - dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0); + dpi = (gdouble) height * PX_PER_IN / area.height(); } if (!sp_export_width) { - width = (unsigned long int) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); + width = (unsigned long int) (area.width() * dpi / PX_PER_IN + 0.5); } if (!sp_export_height) { - height = (unsigned long int) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); + height = (unsigned long int) (area.height() * dpi / PX_PER_IN + 0.5); } guint32 bgcolor = 0x00000000; @@ -1307,12 +1301,12 @@ sp_do_export_png(SPDocument *doc) g_print("Background RRGGBBAA: %08x\n", bgcolor); - g_print("Area %g:%g:%g:%g exported to %lu x %lu pixels (%g dpi)\n", area.x0, area.y0, area.x1, area.y1, width, height, dpi); + g_print("Area %g:%g:%g:%g exported to %lu x %lu pixels (%g dpi)\n", area[Geom::X][0], area[Geom::Y][0], area[Geom::X][1], area[Geom::Y][1], width, height, dpi); g_print("Bitmap saved as: %s\n", filename); if ((width >= 1) && (height >= 1) && (width <= PNG_UINT_31_MAX) && (height <= PNG_UINT_31_MAX)) { - sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL); + sp_export_png_file(doc, filename, area, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL); } else { g_warning("Calculated bitmap dimensions %lu %lu are out of range (1 - %lu). Nothing exported.", width, height, (unsigned long int)PNG_UINT_31_MAX); } diff --git a/src/node-context.cpp b/src/node-context.cpp index 9ff7257ce..c6c639631 100644 --- a/src/node-context.cpp +++ b/src/node-context.cpp @@ -444,7 +444,7 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) if (event->type == GDK_BUTTON_RELEASE) { event_context->xp = event_context->yp = 0; if (event->button.button == 1) { - boost::optional<Geom::Rect> b = Inkscape::Rubberband::get(desktop)->getRectangle(); + Geom::OptRect b = Inkscape::Rubberband::get(desktop)->getRectangle(); if (nc->shape_editor->hits_curve() && !event_context->within_tolerance) { //drag curve nc->shape_editor->finish_drag(); @@ -634,7 +634,7 @@ sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) break; case GDK_Escape: { - boost::optional<Geom::Rect> const b = Inkscape::Rubberband::get(desktop)->getRectangle(); + Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); if (b) { Inkscape::Rubberband::get(desktop)->stop(); nc->current_state = SP_NODE_CONTEXT_INACTIVE; diff --git a/src/nodepath.cpp b/src/nodepath.cpp index 3481f6ed2..34c850d08 100644 --- a/src/nodepath.cpp +++ b/src/nodepath.cpp @@ -126,14 +126,14 @@ static void sp_node_adjust_handles_auto(Inkscape::NodePath::Node *node); static void node_clicked(SPKnot *knot, guint state, gpointer data); static void node_grabbed(SPKnot *knot, guint state, gpointer data); static void node_ungrabbed(SPKnot *knot, guint state, gpointer data); -static gboolean node_request(SPKnot *knot, Geom::Point *p, guint state, gpointer data); +static gboolean node_request(SPKnot *knot, Geom::Point const &p, guint state, gpointer data); /* Handle event callbacks */ static void node_handle_clicked(SPKnot *knot, guint state, gpointer data); static void node_handle_grabbed(SPKnot *knot, guint state, gpointer data); static void node_handle_ungrabbed(SPKnot *knot, guint state, gpointer data); -static gboolean node_handle_request(SPKnot *knot, Geom::Point *p, guint state, gpointer data); -static void node_handle_moved(SPKnot *knot, Geom::Point *p, guint state, gpointer data); +static gboolean node_handle_request(SPKnot *knot, Geom::Point const &p, guint state, gpointer data); +static void node_handle_moved(SPKnot *knot, Geom::Point const &p, guint state, gpointer data); static gboolean node_handle_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::Node *n); /* Constructors and destructors */ @@ -181,7 +181,7 @@ canvasitem_from_pathvec(Inkscape::NodePath::Path *np, Geom::PathVector const &pa static void sp_nodepath_create_helperpaths(Inkscape::NodePath::Path *np) { - //std::map<Inkscape::LivePathEffect::Effect *, std::vector<SPCanvasItem *> >* helper_path_vec; + //std::map<Inkscape::LivePathEffect::Effect *, std::vector<SPCanvasItem *> > helper_path_vec; if (!SP_IS_LPE_ITEM(np->item)) { g_print ("Only LPEItems can have helperpaths!\n"); return; @@ -196,7 +196,7 @@ sp_nodepath_create_helperpaths(Inkscape::NodePath::Path *np) { // create new canvas items from the effect's helper paths std::vector<Geom::PathVector> hpaths = lpe->getHelperPaths(lpeitem); for (std::vector<Geom::PathVector>::iterator j = hpaths.begin(); j != hpaths.end(); ++j) { - (*np->helper_path_vec)[lpe].push_back(canvasitem_from_pathvec(np, *j, true)); + np->helper_path_vec[lpe].push_back(canvasitem_from_pathvec(np, *j, true)); } } } @@ -204,7 +204,7 @@ sp_nodepath_create_helperpaths(Inkscape::NodePath::Path *np) { void sp_nodepath_update_helperpaths(Inkscape::NodePath::Path *np) { - //std::map<Inkscape::LivePathEffect::Effect *, std::vector<SPCanvasItem *> >* helper_path_vec; + //std::map<Inkscape::LivePathEffect::Effect *, std::vector<SPCanvasItem *> > helper_path_vec; if (!SP_IS_LPE_ITEM(np->item)) { g_print ("Only LPEItems can have helperpaths!\n"); return; @@ -223,7 +223,7 @@ sp_nodepath_update_helperpaths(Inkscape::NodePath::Path *np) { for (unsigned int j = 0; j < hpaths.size(); ++j) { SPCurve *curve = new SPCurve(hpaths[j]); curve->transform(np->i2d); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(((*np->helper_path_vec)[lpe])[j]), curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH((np->helper_path_vec[lpe])[j]), curve); curve = curve->unref(); } } @@ -232,18 +232,21 @@ sp_nodepath_update_helperpaths(Inkscape::NodePath::Path *np) { static void sp_nodepath_destroy_helperpaths(Inkscape::NodePath::Path *np) { - for (HelperPathList::iterator i = np->helper_path_vec->begin(); i != np->helper_path_vec->end(); ++i) { + for (HelperPathList::iterator i = np->helper_path_vec.begin(); i != np->helper_path_vec.end(); ++i) { for (std::vector<SPCanvasItem *>::iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) { GtkObject *temp = *j; *j = NULL; gtk_object_destroy(temp); } } + np->helper_path_vec.clear(); } /** * \brief Creates new nodepath from item + * + * \todo create proper constructor for nodepath::path, this method returns null a constructor cannot so this cannot be simply converted to constructor. */ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, bool show_handles, const char * repr_key_in, SPItem *item) { @@ -278,7 +281,7 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, } //Create new nodepath - Inkscape::NodePath::Path *np = g_new(Inkscape::NodePath::Path, 1); + Inkscape::NodePath::Path *np = new Inkscape::NodePath::Path(); if (!np) { curve->unref(); return NULL; @@ -295,7 +298,6 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, np->local_change = 0; np->show_handles = show_handles; np->helper_path = NULL; - np->helper_path_vec = new HelperPathList; np->helperpath_rgba = prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff); np->helperpath_width = 1.0; np->curve = curve->copy(); @@ -328,7 +330,7 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, Inkscape::LivePathEffect::Effect * lpe = LIVEPATHEFFECT(object)->get_lpe(); if (!lpe) { g_error("sp_nodepath_new: lpeobject without real lpe passed as argument!"); - sp_nodepath_destroy(np); + delete np; } Inkscape::LivePathEffect::Parameter *lpeparam = lpe->getParameter(repr_key_in); if (lpeparam) { @@ -383,48 +385,39 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, /** * Destroys nodepath's subpaths, then itself, also tell parent ShapeEditor about it. */ -void sp_nodepath_destroy(Inkscape::NodePath::Path *np) { - - if (!np) { //soft fail, like delete - return; - } - - while (np->subpaths) { - sp_nodepath_subpath_destroy((Inkscape::NodePath::SubPath *) np->subpaths->data); +Inkscape::NodePath::Path::~Path() { + while (this->subpaths) { + sp_nodepath_subpath_destroy((Inkscape::NodePath::SubPath *) this->subpaths->data); } //Inform the ShapeEditor that made me, if any, that I am gone. - if (np->shape_editor) - np->shape_editor->nodepath_destroyed(); + if (this->shape_editor) + this->shape_editor->nodepath_destroyed(); - g_assert(!np->selected); + g_assert(!this->selected); - if (np->helper_path) { - GtkObject *temp = np->helper_path; - np->helper_path = NULL; + if (this->helper_path) { + GtkObject *temp = this->helper_path; + this->helper_path = NULL; gtk_object_destroy(temp); } - if (np->curve) { - np->curve->unref(); - np->curve = NULL; + if (this->curve) { + this->curve->unref(); + this->curve = NULL; } - if (np->repr_key) { - g_free(np->repr_key); - np->repr_key = NULL; + if (this->repr_key) { + g_free(this->repr_key); + this->repr_key = NULL; } - if (np->repr_nodetypes_key) { - g_free(np->repr_nodetypes_key); - np->repr_nodetypes_key = NULL; + if (this->repr_nodetypes_key) { + g_free(this->repr_nodetypes_key); + this->repr_nodetypes_key = NULL; } - sp_nodepath_destroy_helperpaths(np); - delete np->helper_path_vec; - np->helper_path_vec = NULL; - - np->desktop = NULL; + sp_nodepath_destroy_helperpaths(this); - g_free(np); + this->desktop = NULL; } /** @@ -771,6 +764,9 @@ static SPCurve *create_curve(Inkscape::NodePath::Path *np) Inkscape::NodePath::Node *n = sp->first->n.other; while (n) { Geom::Point const end_pt = n->pos * np->d2i; + if (!IS_FINITE(n->pos[0]) || !IS_FINITE(n->pos[1])){ + g_message("niet finite"); + } switch (n->code) { case NR_LINETO: curve->lineto(end_pt); @@ -2067,6 +2063,9 @@ sp_nodepath_add_node_near_point(Inkscape::NodePath::Path *nodepath, Geom::Point //find segment to split Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(nodepath, segment_index); + if (!e) { + return; + } //don't know why but t seems to flip for lines if (sp_node_path_code_from_side(e, sp_node_get_side(e, -1)) == NR_LINETO) { @@ -3609,7 +3608,7 @@ static double point_line_distance(Geom::Point *p, double a) * \todo fixme: This goes to "moved" event? (lauris) */ static gboolean -node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) +node_request(SPKnot */*knot*/, Geom::Point const &p, guint state, gpointer data) { double yn, xn, yp, xp; double an, ap, na, pa; @@ -3627,12 +3626,12 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) ( ((state & GDK_SHIFT_MASK) && ((n->n.other && n->n.pos == n->pos) || (n->p.other && n->p.pos == n->pos))) || n->dragging_out ) ) { - Geom::Point mouse = (*p); + Geom::Point mouse = p; if (!n->dragging_out) { // This is the first drag-out event; find out which handle to drag out - double appr_n = (n->n.other ? Geom::L2(n->n.other->pos - n->pos) - Geom::L2(n->n.other->pos - (*p)) : -HUGE_VAL); - double appr_p = (n->p.other ? Geom::L2(n->p.other->pos - n->pos) - Geom::L2(n->p.other->pos - (*p)) : -HUGE_VAL); + double appr_n = (n->n.other ? Geom::L2(n->n.other->pos - n->pos) - Geom::L2(n->n.other->pos - p) : -HUGE_VAL); + double appr_p = (n->p.other ? Geom::L2(n->p.other->pos - n->pos) - Geom::L2(n->p.other->pos - p) : -HUGE_VAL); if (appr_p == -HUGE_VAL && appr_n == -HUGE_VAL) // orphan node? return FALSE; @@ -3656,8 +3655,8 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) opposite = &n->p; n->n.other->code = NR_CURVETO; } else { // find out to which handle of the adjacent node we're closer; note that n->n.other == n->p.other - double appr_other_n = (n->n.other ? Geom::L2(n->n.other->n.pos - n->pos) - Geom::L2(n->n.other->n.pos - (*p)) : -HUGE_VAL); - double appr_other_p = (n->n.other ? Geom::L2(n->n.other->p.pos - n->pos) - Geom::L2(n->n.other->p.pos - (*p)) : -HUGE_VAL); + double appr_other_n = (n->n.other ? Geom::L2(n->n.other->n.pos - n->pos) - Geom::L2(n->n.other->n.pos - p) : -HUGE_VAL); + double appr_other_p = (n->n.other ? Geom::L2(n->n.other->p.pos - n->pos) - Geom::L2(n->n.other->p.pos - p) : -HUGE_VAL); if (appr_other_p > appr_other_n) { // closer to other's p handle n->dragging_out = &n->n; opposite = &n->p; @@ -3681,7 +3680,7 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) } // pass this on to the handle-moved callback - node_handle_moved(n->dragging_out->knot, &mouse, state, (gpointer) n); + node_handle_moved(n->dragging_out->knot, mouse, state, (gpointer) n); sp_node_update_handles(n); return TRUE; } @@ -3744,7 +3743,7 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) if (ap == 0) pa = HUGE_VAL; else pa = -1/ap; // mouse point relative to the node's original pos - pr = (*p) - n->origin; + pr = p - n->origin; // distances to the four lines (two handles and two perpendiculars) d_an = point_line_distance(&pr, an); @@ -3771,16 +3770,16 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) } else { // constraining to hor/vert - if (fabs((*p)[Geom::X] - n->origin[Geom::X]) > fabs((*p)[Geom::Y] - n->origin[Geom::Y])) { // snap to hor + if (fabs(p[Geom::X] - n->origin[Geom::X]) > fabs(p[Geom::Y] - n->origin[Geom::Y])) { // snap to hor sp_nodepath_selected_nodes_move(n->subpath->nodepath, - (*p)[Geom::X] - n->pos[Geom::X], + p[Geom::X] - n->pos[Geom::X], n->origin[Geom::Y] - n->pos[Geom::Y], true, true, Inkscape::Snapper::ConstraintLine(component_vectors[Geom::X])); } else { // snap to vert sp_nodepath_selected_nodes_move(n->subpath->nodepath, n->origin[Geom::X] - n->pos[Geom::X], - (*p)[Geom::Y] - n->pos[Geom::Y], + p[Geom::Y] - n->pos[Geom::Y], true, true, Inkscape::Snapper::ConstraintLine(component_vectors[Geom::Y])); } @@ -3788,17 +3787,17 @@ node_request(SPKnot */*knot*/, Geom::Point *p, guint state, gpointer data) } else { // move freely if (n->is_dragging) { if (state & GDK_MOD1_MASK) { // sculpt - sp_nodepath_selected_nodes_sculpt(n->subpath->nodepath, n, (*p) - n->origin); + sp_nodepath_selected_nodes_sculpt(n->subpath->nodepath, n, p - n->origin); } else { sp_nodepath_selected_nodes_move(n->subpath->nodepath, - (*p)[Geom::X] - n->pos[Geom::X], - (*p)[Geom::Y] - n->pos[Geom::Y], + p[Geom::X] - n->pos[Geom::X], + p[Geom::Y] - n->pos[Geom::Y], (state & GDK_SHIFT_MASK) == 0); } } } - n->subpath->nodepath->desktop->scroll_to_point(*p); + n->subpath->nodepath->desktop->scroll_to_point(p); return TRUE; } @@ -3879,7 +3878,7 @@ static void node_handle_ungrabbed(SPKnot *knot, guint state, gpointer data) /** * Node handle "request" signal callback. */ -static gboolean node_handle_request(SPKnot *knot, Geom::Point *p, guint state, gpointer data) +static gboolean node_handle_request(SPKnot *knot, Geom::Point const &p, guint state, gpointer data) { Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; @@ -3907,40 +3906,37 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point *p, guint state, g if ((state & GDK_SHIFT_MASK) != 0) { // We will not try to snap when the shift-key is pressed // so remove the old snap indicator and don't wait for it to time-out - desktop->snapindicator->remove_snappoint(); + desktop->snapindicator->remove_snappoint(); } Inkscape::NodePath::Node *othernode = opposite->other; if (othernode) { if ((n->type != Inkscape::NodePath::NODE_CUSP) && sp_node_side_is_line(n, opposite)) { /* We are smooth node adjacent with line */ - Geom::Point const delta = *p - n->pos; + Geom::Point const delta = p - n->pos; Geom::Coord const len = Geom::L2(delta); Inkscape::NodePath::Node *othernode = opposite->other; Geom::Point const ndelta = n->pos - othernode->pos; Geom::Coord const linelen = Geom::L2(ndelta); + Geom::Point ptemp = p; if (len > NR_EPSILON && linelen > NR_EPSILON) { Geom::Coord const scal = dot(delta, ndelta) / linelen; - (*p) = n->pos + (scal / linelen) * ndelta; + ptemp = n->pos + (scal / linelen) * ndelta; } if ((state & GDK_SHIFT_MASK) == 0) { - s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(*p), Inkscape::Snapper::ConstraintLine(*p, ndelta)); + s = m.constrainedSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, ptemp, Inkscape::Snapper::ConstraintLine(ptemp, ndelta)); } } else { - if ((state & GDK_SHIFT_MASK) == 0) { - s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(*p)); - } + if ((state & GDK_SHIFT_MASK) == 0) { + s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p); + } } } else { - if ((state & GDK_SHIFT_MASK) == 0) { - s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, to_2geom(*p)); - } + if ((state & GDK_SHIFT_MASK) == 0) { + s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p); + } } - Geom::Point pt2g = *p; - s.getPoint(pt2g); - *p = pt2g; - sp_node_adjust_handle(n, -which); return FALSE; @@ -3949,7 +3945,7 @@ static gboolean node_handle_request(SPKnot *knot, Geom::Point *p, guint state, g /** * Node handle moved callback. */ -static void node_handle_moved(SPKnot *knot, Geom::Point *p, guint state, gpointer data) +static void node_handle_moved(SPKnot *knot, Geom::Point const &p, guint state, gpointer data) { Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -3971,7 +3967,7 @@ static void node_handle_moved(SPKnot *knot, Geom::Point *p, guint state, gpointe // calculate radial coordinates of the grabbed handle, its other handle, and the mouse point Radial rme(me->pos - n->pos); Radial rother(other->pos - n->pos); - Radial rnew(*p - n->pos); + Radial rnew(p - n->pos); if (state & GDK_CONTROL_MASK && rnew.a != HUGE_VAL) { int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); @@ -4362,8 +4358,18 @@ void sp_nodepath_selected_nodes_scale(Inkscape::NodePath::Path *nodepath, gdoubl box.expandTo (n->pos); // contain all selected nodes } + if ( Geom::are_near(box.maxExtent(), 0) ) { + SPEventContext *ec = nodepath->desktop->event_context; + if (!ec) return; + Inkscape::MessageContext *mc = get_message_context(ec); + if (!mc) return; + mc->setF(Inkscape::WARNING_MESSAGE, + _("Cannot scale nodes when all are at the same location.")); + return; + } double scale = (box.maxExtent() + grow)/box.maxExtent(); + Geom::Point scale_center; if (Inkscape::NodePath::Path::active_node == NULL) scale_center = box.midpoint(); @@ -4371,9 +4377,9 @@ void sp_nodepath_selected_nodes_scale(Inkscape::NodePath::Path *nodepath, gdoubl scale_center = Inkscape::NodePath::Path::active_node->pos; Geom::Matrix t = - Geom::Matrix (Geom::Translate(-scale_center)) * - Geom::Matrix (Geom::Scale(scale, scale)) * - Geom::Matrix (Geom::Translate(scale_center)); + Geom::Translate(-scale_center) * + Geom::Scale(scale, scale) * + Geom::Translate(scale_center); for (GList *l = nodepath->selected; l != NULL; l = l->next) { Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; diff --git a/src/nodepath.h b/src/nodepath.h index 4d05b9f01..262b93d04 100644 --- a/src/nodepath.h +++ b/src/nodepath.h @@ -51,25 +51,25 @@ typedef std::map<Inkscape::LivePathEffect::Effect *, std::vector<SPCanvasItem *> class Radial{ public: /** Radius */ - double r; + double r; /** Amplitude */ - double a; - Radial() {} - // Radial(Geom::Point const &p); // Convert a point to radial coordinates - Radial(Radial &p) : r(p.r),a(p.a) {} - // operator Geom::Point() const; + double a; + Radial() {} + // Radial(Geom::Point const &p); // Convert a point to radial coordinates + Radial(Radial &p) : r(p.r),a(p.a) {} + // operator Geom::Point() const; /** * Construct Radial from Geom::Point. */ Radial(Geom::Point const &p) { - r = Geom::L2(p); - if (r > 0) { - a = Geom::atan2 (p); - } else { - a = HUGE_VAL; //undefined - } + r = Geom::L2(p); + if (r > 0) { + a = Geom::atan2 (p); + } else { + a = HUGE_VAL; //undefined + } } /** @@ -77,11 +77,11 @@ Radial(Geom::Point const &p) */ operator Geom::Point() const { - if (a == HUGE_VAL) { - return Geom::Point(0,0); - } else { - return r*Geom::Point(cos(a), sin(a)); - } + if (a == HUGE_VAL) { + return Geom::Point(0,0); + } else { + return r*Geom::Point(cos(a), sin(a)); + } } }; @@ -118,15 +118,15 @@ class Node; class SubPath { public: /** The parent of this subpath */ - Path * nodepath; + Path * nodepath; /** Is this path closed (no endpoints) or not?*/ - gboolean closed; + gboolean closed; /** The nodes in this subpath. */ - GList * nodes; + GList * nodes; /** The first node of the subpath (does not imply open/closed)*/ - Node * first; + Node * first; /** The last node of the subpath */ - Node * last; + Node * last; }; @@ -140,15 +140,15 @@ class SubPath { */ typedef enum { /** A normal node */ - NODE_NONE, + NODE_NONE, /** This node non-continuously joins two segments.*/ - NODE_CUSP, + NODE_CUSP, /** This node continuously joins two segments. */ - NODE_SMOOTH, + NODE_SMOOTH, /** This node has automatic handles. */ - NODE_AUTO, + NODE_AUTO, /** This node is symmetric. */ - NODE_SYMM + NODE_SYMM } NodeType; @@ -160,19 +160,19 @@ typedef enum { class NodeSide{ public: /** Pointer to the next node, */ - Node * other; + Node * other; /** Position */ - Geom::Point pos; + Geom::Point pos; /** Origin (while dragging) in radial notation */ - Radial origin_radial; + Radial origin_radial; /** Origin (while dragging) in x/y notation */ - Geom::Point origin; + Geom::Point origin; /** Knots are Inkscape's way of providing draggable points. This * Knot is the point on the curve representing the control point in a * bezier curve.*/ - SPKnot * knot; + SPKnot * knot; /** What kind of rendering? */ - SPCanvasItem * line; + SPCanvasItem * line; }; /** @@ -181,28 +181,28 @@ class NodeSide{ class Node { public: /** The parent subpath of this node */ - SubPath * subpath; + SubPath * subpath; /** Type is selected from NodeType.*/ - guint type : 4; + guint type : 4; /** Code refers to which ArtCode is used to represent the segment * (which segment?).*/ - guint code : 4; + guint code : 4; /** Boolean. Am I currently selected or not? */ - guint selected : 1; + guint selected : 1; /** */ - Geom::Point pos; + Geom::Point pos; /** */ - Geom::Point origin; + Geom::Point origin; /** Knots are Inkscape's way of providing draggable points. This * Knot is the point on the curve representing the endpoint.*/ - SPKnot * knot; + SPKnot * knot; /** The NodeSide in the 'next' direction */ - NodeSide n; + NodeSide n; /** The NodeSide in the 'previous' direction */ - NodeSide p; + NodeSide p; - /** The pointer to the nodeside which we are dragging out with Shift */ - NodeSide *dragging_out; + /** The pointer to the nodeside which we are dragging out with Shift */ + NodeSide *dragging_out; /** Boolean. Am I being dragged? */ guint is_dragging : 1; @@ -221,30 +221,37 @@ class Node { */ class Path { public: + /** Constructor should private, people should create new nodepaths using sp_nodepath_new + * But for some reason I cannot make sp_nodepath_new a friend :-( + */ + Path() {}; + /** Destructor */ + ~Path(); + /** Pointer to the current desktop, for reporting purposes */ - SPDesktop * desktop; + SPDesktop * desktop; /** The parent path of this nodepath */ - SPObject * object; + SPObject * object; /** The parent livepatheffect of this nodepath, if applicable */ SPItem * item; /** The context which created this nodepath. Important if this nodepath is deleted */ - ShapeEditor *shape_editor; + ShapeEditor *shape_editor; /** The subpaths which comprise this NodePath */ - GList * subpaths; + GList * subpaths; /** A list of nodes which are currently selected */ - GList * selected; + GList * selected; /** Transforms (userspace <---> virtual space? someone please describe ) - njh: I'd be guessing that these are item <-> desktop transforms.*/ - Geom::Matrix i2d, d2i; + njh: I'd be guessing that these are item <-> desktop transforms.*/ + Geom::Matrix i2d, d2i; /** The DOM node which describes this NodePath */ Inkscape::XML::Node *repr; gchar *repr_key; gchar *repr_nodetypes_key; - //STL compliant method to get the selected nodes - void selection(std::list<Node *> &l); + //STL compliant method to get the selected nodes + void selection(std::list<Node *> &l); - guint numSelected() {return (selected? g_list_length(selected) : 0);} - Geom::Point& singleSelectedCoords() {return (((Node *) selected->data)->pos);} + guint numSelected() {return (selected? g_list_length(selected) : 0);} + Geom::Point& singleSelectedCoords() {return (((Node *) selected->data)->pos);} /// draw a "sketch" of the path by using these variables SPCanvasItem *helper_path; @@ -254,21 +261,21 @@ class Path { gdouble helperpath_width; // the helperpaths provided by all LPEs (and their paramaters) of the current item - HelperPathList* helper_path_vec; + HelperPathList helper_path_vec; /// true if we changed repr, to tell this change from an external one such as from undo, simplify, or another desktop - unsigned int local_change; + unsigned int local_change; - /// true if we're showing selected nodes' handles - bool show_handles; + /// true if we're showing selected nodes' handles + bool show_handles; /// true if the path cannot contain curves, just straight lines bool straight_path; - /// active_node points to the node that is currently mouseovered (= NULL if - /// there isn't any); we also consider the node mouseovered if it is covered - /// by one of its handles and the latter is mouseovered - static Node *active_node; + /// active_node points to the node that is currently mouseovered (= NULL if + /// there isn't any); we also consider the node mouseovered if it is covered + /// by one of its handles and the latter is mouseovered + static Node *active_node; }; } // namespace NodePath @@ -282,7 +289,6 @@ enum { // Do function documentation in nodepath.cpp Inkscape::NodePath::Path * sp_nodepath_new (SPDesktop * desktop, SPObject *object, bool show_handles, const char * repr_key = NULL, SPItem *item = NULL); -void sp_nodepath_destroy (Inkscape::NodePath::Path * nodepath); void sp_nodepath_deselect (Inkscape::NodePath::Path *nodepath); void sp_nodepath_select_all (Inkscape::NodePath::Path *nodepath, bool invert); void sp_nodepath_select_all_from_subpath(Inkscape::NodePath::Path *nodepath, bool invert); diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 0458add78..1fd566c82 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -138,7 +138,7 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, if (SP_IS_GROUP(o)) { _findCandidates(o, it, false, bbox_to_snap, snap_dim, false, Geom::identity()); } else { - boost::optional<Geom::Rect> bbox_of_item = Geom::Rect(); + Geom::OptRect bbox_of_item = Geom::Rect(); if (clip_or_mask) { // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine) @@ -215,7 +215,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox // of the item AND the bbox of the clipping path at the same time if (!(*i).clip_or_mask) { - boost::optional<Geom::Rect> b = sp_item_bbox_desktop(root_item, bbox_type); + Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type); if (b) { for ( unsigned k = 0 ; k < 4 ; k++ ) { _points_to_snap_to->push_back(b->corner(k)); @@ -378,11 +378,12 @@ void Inkscape::ObjectSnapper::_collectPaths(Inkscape::SnapPreferences::PointType // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox // of the item AND the bbox of the clipping path at the same time if (!(*i).clip_or_mask) { - NRRect rect; - sp_item_invoke_bbox(root_item, &rect, i2doc, TRUE, bbox_type); - Geom::Rect const rect2 = to_2geom(*rect.upgrade()); - Geom::PathVector *path = _getPathvFromRect(rect2); - _paths_to_snap_to->push_back(path); + Geom::OptRect rect; + sp_item_invoke_bbox(root_item, rect, i2doc, TRUE, bbox_type); + if (rect) { + Geom::PathVector *path = _getPathvFromRect(*rect); + _paths_to_snap_to->push_back(path); + } } } } @@ -406,8 +407,9 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, bool const node_tool_active = _snap_to_itempath && selected_path != NULL; if (first_point) { - /* While editing a path in the node tool, findCandidates must ignore that path because - * of the node snapping requirements (i.e. only unselected nodes must be snapable). + /* findCandidates() is used for snapping to both paths and nodes. It ignores the path that is + * currently being edited, because that path requires special care: when snapping to nodes + * only the unselected nodes of that path should be considered, and these will be passed on separately. * This path must not be ignored however when snapping to the paths, so we add it here * manually when applicable. * @@ -452,8 +454,15 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, g_assert(unselected_nodes != NULL); Geom::Point start_pt = _snapmanager->getDesktop()->doc2dt(curve->pointAt(0)); Geom::Point end_pt = _snapmanager->getDesktop()->doc2dt(curve->pointAt(1)); - c1 = isUnselectedNode(start_pt, unselected_nodes); - c2 = isUnselectedNode(end_pt, unselected_nodes); + c1 = isUnselectedNode(start_pt, unselected_nodes); + c2 = isUnselectedNode(end_pt, unselected_nodes); + /* Unfortunately, this might yield false positives for coincident nodes. Inkscape might therefore mistakenly + * snap to path segments that are not stationary. There are at least two possible ways to overcome this: + * - Linking the individual nodes of the SPPath we have here, to the nodes of the NodePath::SubPath class as being + * used in sp_nodepath_selected_nodes_move. This class has a member variable called "selected". For this the nodes + * should be in the exact same order for both classes, so we can index them + * - Replacing the SPPath being used here by the the NodePath::SubPath class; but how? + */ } Geom::Point const sp_dt = _snapmanager->getDesktop()->doc2dt(sp_doc); @@ -550,7 +559,7 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, std::vector<SPItem const *> const *it, std::vector<Geom::Point> *unselected_nodes) const { @@ -593,7 +602,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, ConstraintLine const &c, std::vector<SPItem const *> const *it) const { diff --git a/src/object-snapper.h b/src/object-snapper.h index 01ef8cf50..f235ae566 100644 --- a/src/object-snapper.h +++ b/src/object-snapper.h @@ -77,7 +77,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, std::vector<SPItem const *> const *it, std::vector<Geom::Point> *unselected_nodes) const; @@ -85,7 +85,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, bool const &first_point, - boost::optional<Geom::Rect> const &bbox_to_snap, + Geom::OptRect const &bbox_to_snap, ConstraintLine const &c, std::vector<SPItem const *> const *it) const; diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index acc10389c..69d9a5e23 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -58,7 +58,7 @@ static void spdc_set_endpoint(SPPencilContext *pc, Geom::Point const p); static void spdc_finish_endpoint(SPPencilContext *pc); static void spdc_add_freehand_point(SPPencilContext *pc, Geom::Point p, guint state); static void fit_and_split(SPPencilContext *pc); - +static void interpolate(SPPencilContext *pc); static SPDrawContextClass *pencil_parent_class; static Geom::Point pencil_drag_origin_w(0, 0); @@ -263,9 +263,9 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p); if (s.getSnapped()) { s.getPoint(p); - pc->pencil_has_snapped_before = true; + pc->prev_snap_was_succesful = true; } else { - pc->pencil_has_snapped_before = false; + pc->prev_snap_was_succesful = false; } } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path")); @@ -362,11 +362,13 @@ pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mev Inkscape::SnappedPoint const s = m.freeSnap(Inkscape::SnapPreferences::SNAPPOINT_NODE, p); if (s.getSnapped()) { s.getPoint(p); - pc->pencil_has_snapped_before = true; + pc->prev_snap_was_succesful = true; + } else { + pc->prev_snap_was_succesful = false; } } if ( pc->npoints != 0) { // buttonpress may have happened before we entered draw context! - if (!(pc->pencil_has_snapped_before && m.snapprefs.getSnapPostponedGlobally())) { + if (!(pc->prev_snap_was_succesful && m.snapprefs.getSnapPostponedGlobally())) { // When snapping is enabled but temporarily on hold because the mouse is moving // fast, then we don't want to add nodes off-grid spdc_add_freehand_point(pc, from_2geom(p), mevent.state); @@ -450,6 +452,7 @@ pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &re dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand")); + interpolate(pc); spdc_concat_colors_and_flush(pc, FALSE); pc->sa = NULL; pc->ea = NULL; @@ -624,6 +627,7 @@ spdc_finish_endpoint(SPPencilContext *const pc) } } + static void spdc_add_freehand_point(SPPencilContext *pc, Geom::Point p, guint /*state*/) { @@ -633,6 +637,7 @@ spdc_add_freehand_point(SPPencilContext *pc, Geom::Point p, guint /*state*/) if ( ( p != pc->p[ pc->npoints - 1 ] ) && in_svg_plane(p) ) { + pc->ps.push_back(p); pc->p[pc->npoints++] = p; fit_and_split(pc); } @@ -645,21 +650,94 @@ square(double const x) } static void +interpolate(SPPencilContext *pc) +{ + + g_assert( pc->ps.size() > 1 ); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; + double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() * + tol) * exp(0.2*tol - 2); + + g_assert(is_zero(pc->req_tangent) + || is_unit_vector(pc->req_tangent)); + Geom::Point const tHatEnd(0, 0); + + guint n_points = pc->ps.size(); + pc->green_curve->reset(); + pc->red_curve->reset(); + + Geom::Point * b = g_new(Geom::Point, 4*n_points); + Geom::Point * points = g_new(Geom::Point, 4*n_points); + for (int i = 0; i < pc->ps.size(); i++) { + points[i] = pc->ps[i]; + } + + // worst case gives us a segment per point + int max_segs = 4*n_points; + + int const n_segs = sp_bezier_fit_cubic_r(b, points, n_points, + tolerance_sq, max_segs); + + if ( n_segs > 0) + { + /* Fit and draw and reset state */ + pc->red_curve->reset(); + pc->red_curve->moveto(b[0]); + for (int c = 0; c < n_segs; c++) { + pc->red_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); + } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + pc->red_curve_is_valid = true; + + /* Fit and draw and copy last point */ + g_assert(!pc->red_curve->is_empty()); + + /* Set up direction of next curve. */ + { + Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->red_curve->last_segment()); + g_assert( last_seg ); // Relevance: validity of (*last_seg)[2] + pc->p[0] = last_seg->finalPoint(); + pc->npoints = 1; + Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] ); + pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) ) + ? Geom::Point(0, 0) + : Geom::unit_vector(req_vec) ); + } + + pc->green_curve->append_continuous(pc->red_curve, 0.0625); + SPCurve *curve = pc->red_curve->copy(); + + /// \todo fixme: + SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), curve); + curve->unref(); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + + pc->red_curve_is_valid = false; + } + g_free(b); + g_free(points); + pc->ps.clear(); +} + + +static void fit_and_split(SPPencilContext *pc) { g_assert( pc->npoints > 1 ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() * tol) - * exp(0.2*tol - 2); + double const tolerance_sq = 0; Geom::Point b[4]; g_assert(is_zero(pc->req_tangent) || is_unit_vector(pc->req_tangent)); Geom::Point const tHatEnd(0, 0); int const n_segs = sp_bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints, - pc->req_tangent, tHatEnd, tolerance_sq, 1); + pc->req_tangent, tHatEnd, + tolerance_sq, 1); if ( n_segs > 0 && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) ) { diff --git a/src/pencil-context.h b/src/pencil-context.h index 467241b17..0845c82ba 100644 --- a/src/pencil-context.h +++ b/src/pencil-context.h @@ -30,7 +30,9 @@ struct SPPencilContext : public SPDrawContext { Geom::Point req_tangent; bool is_drawing; - bool pencil_has_snapped_before; + bool prev_snap_was_succesful; + + std::vector<Geom::Point> ps; }; /// The SPPencilContext vtable (empty). diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index c6b547a9e..0b8601748 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -248,6 +248,8 @@ static char const preferences_skeleton[] = " <group id=\"wheelzooms\" value=\"0\"/>\n" " <group id=\"transientpolicy\" value=\"1\"/>\n" " <group id=\"scrollingacceleration\" value=\"0.4\"/>\n" +" <group id=\"snapdelay\" value=\"150\"/>\n" +" <group id=\"snapindicator\" value=\"1\"/>\n" " <group id=\"autoscrollspeed\" value=\"0.7\"/>\n" " <group id=\"autoscrolldistance\" value=\"-10\"/>\n" " <group id=\"simplifythreshold\" value=\"0.002\"/>\n" diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp index 60bb0e4f9..084f95dfe 100644 --- a/src/removeoverlap/removeoverlap.cpp +++ b/src/removeoverlap/removeoverlap.cpp @@ -48,7 +48,7 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG ++it) { using Geom::X; using Geom::Y; - boost::optional<Geom::Rect> item_box(sp_item_bbox_desktop(*it)); + Geom::OptRect item_box(sp_item_bbox_desktop(*it)); if (item_box) { Geom::Point min(item_box->min() - .5*gap); Geom::Point max(item_box->max() + .5*gap); diff --git a/src/rubberband.cpp b/src/rubberband.cpp index 7c43da9ea..76743cf8b 100644 --- a/src/rubberband.cpp +++ b/src/rubberband.cpp @@ -124,10 +124,10 @@ void Inkscape::Rubberband::setMode(int mode) _mode = mode; } -boost::optional<Geom::Rect> Inkscape::Rubberband::getRectangle() const +Geom::OptRect Inkscape::Rubberband::getRectangle() const { if (!_started) { - return boost::optional<Geom::Rect>(); + return Geom::OptRect(); } return Geom::Rect(_start, _end); diff --git a/src/rubberband.h b/src/rubberband.h index 6da1ddd8d..1f4b7d2ea 100644 --- a/src/rubberband.h +++ b/src/rubberband.h @@ -40,7 +40,7 @@ public: void start(SPDesktop *desktop, Geom::Point const &p); void move(Geom::Point const &p); - boost::optional<Geom::Rect> getRectangle() const; + Geom::OptRect getRectangle() const; void stop(); bool is_started(); diff --git a/src/selcue.cpp b/src/selcue.cpp index 241802a87..03205d849 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -85,7 +85,7 @@ void Inkscape::SelCue::_updateItemBboxes() for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) { SPItem *item = (SPItem *) l->data; - boost::optional<Geom::Rect> const b = sp_item_bbox_desktop(item, bbox_type); + Geom::OptRect const b = sp_item_bbox_desktop(item, bbox_type); SPCanvasItem* box = NULL; diff --git a/src/select-context.cpp b/src/select-context.cpp index b726243f9..11c9cc4e9 100644 --- a/src/select-context.cpp +++ b/src/select-context.cpp @@ -599,7 +599,7 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) // this was a rubberband drag GSList *items = NULL; if (r->getMode() == RUBBERBAND_MODE_RECT) { - boost::optional<Geom::Rect> const b = r->getRectangle(); + Geom::OptRect const b = r->getRectangle(); items = sp_document_items_in_box(sp_desktop_document(desktop), desktop->dkey, *b); } else if (r->getMode() == RUBBERBAND_MODE_TOUCHPATH) { items = sp_document_items_at_points(sp_desktop_document(desktop), desktop->dkey, r->getPoints()); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 86bf64f01..bd59c0aa4 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -614,12 +614,12 @@ sp_item_list_common_parent_group(GSList const *items) } /** Finds out the minimum common bbox of the selected items. */ -static boost::optional<Geom::Rect> +static Geom::OptRect enclose_items(GSList const *items) { g_assert(items != NULL); - boost::optional<Geom::Rect> r; + Geom::OptRect r; for (GSList const *i = items; i; i = i->next) { r = Geom::unify(r, sp_item_bbox_desktop((SPItem *) i->data)); } @@ -667,7 +667,7 @@ sp_selection_raise(SPDesktop *desktop) rev = g_slist_sort(rev, (GCompareFunc) sp_item_repr_compare_position); // Determine the common bbox of the selected items. - boost::optional<Geom::Rect> selected = enclose_items(items); + Geom::OptRect selected = enclose_items(items); // Iterate over all objects in the selection (starting from top). if (selected) { @@ -677,7 +677,7 @@ sp_selection_raise(SPDesktop *desktop) for (SPObject *newref = child->next; newref; newref = newref->next) { // if the sibling is an item AND overlaps our selection, if (SP_IS_ITEM(newref)) { - boost::optional<Geom::Rect> newref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); + Geom::OptRect newref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); if ( newref_bbox && selected->intersects(*newref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find((GSList *) items, newref)) { @@ -757,7 +757,7 @@ sp_selection_lower(SPDesktop *desktop) Inkscape::XML::Node *grepr = SP_OBJECT_REPR(group); // Determine the common bbox of the selected items. - boost::optional<Geom::Rect> selected = enclose_items(items); + Geom::OptRect selected = enclose_items(items); /* Construct direct-ordered list of selected children. */ GSList *rev = g_slist_copy((GSList *) items); @@ -772,7 +772,7 @@ sp_selection_lower(SPDesktop *desktop) for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) { // if the sibling is an item AND overlaps our selection, if (SP_IS_ITEM(newref)) { - boost::optional<Geom::Rect> ref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); + Geom::OptRect ref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); if ( ref_bbox && selected->intersects(*ref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find((GSList *) items, newref)) { @@ -1285,8 +1285,8 @@ sp_selection_scale_absolute(Inkscape::Selection *selection, if (selection->isEmpty()) return; - boost::optional<Geom::Rect> const bbox(selection->bounds()); - if ( !bbox || bbox->isEmpty() ) { + Geom::OptRect const bbox(selection->bounds()); + if ( !bbox ) { return; } @@ -1307,9 +1307,9 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point con if (selection->isEmpty()) return; - boost::optional<Geom::Rect> const bbox(selection->bounds()); + Geom::OptRect const bbox(selection->bounds()); - if ( !bbox || bbox->isEmpty() ) { + if ( !bbox ) { return; } @@ -1425,7 +1425,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) if (selection->isEmpty()) return; - boost::optional<Geom::Rect> const bbox(selection->bounds()); + Geom::OptRect const bbox(selection->bounds()); boost::optional<Geom::Point> center = selection->center(); if ( !bbox || !center ) { @@ -1454,7 +1454,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) if (selection->isEmpty()) return; - boost::optional<Geom::Rect> const bbox(selection->bounds()); + Geom::OptRect const bbox(selection->bounds()); if (!bbox) { return; } @@ -1491,7 +1491,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) if (selection->isEmpty()) return; - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); if (!sel_bbox) { return; @@ -1815,7 +1815,7 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, void scroll_to_show_item(SPDesktop *desktop, SPItem *item) { Geom::Rect dbox = desktop->get_display_area(); - boost::optional<Geom::Rect> sbox = sp_item_bbox_desktop(item); + Geom::OptRect sbox = sp_item_bbox_desktop(item); if ( sbox && dbox.contains(*sbox) == false ) { Geom::Point const s_dt = sbox->midpoint(); @@ -2046,8 +2046,8 @@ sp_select_clone_original(SPDesktop *desktop) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool highlight = prefs->getBool("/options/highlightoriginal/value"); if (highlight) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2d_affine(item)); - boost::optional<Geom::Rect> b = original->getBounds(sp_item_i2d_affine(original)); + Geom::OptRect a = item->getBounds(sp_item_i2d_affine(item)); + Geom::OptRect b = original->getBounds(sp_item_i2d_affine(original)); if ( a && b ) { // draw a flashing line between the objects SPCurve *curve = new SPCurve(); @@ -2088,9 +2088,9 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) } sp_document_ensure_up_to_date(doc); - boost::optional<Geom::Rect> r = selection->bounds(); + Geom::OptRect r = selection->bounds(); boost::optional<Geom::Point> c = selection->center(); - if ( !r || !c || r->isEmpty() ) { + if ( !r || !c ) { return; } @@ -2212,8 +2212,8 @@ sp_selection_tile(SPDesktop *desktop, bool apply) } sp_document_ensure_up_to_date(doc); - boost::optional<Geom::Rect> r = selection->bounds(); - if ( !r || r->isEmpty() ) { + Geom::OptRect r = selection->bounds(); + if ( !r ) { return; } @@ -2871,8 +2871,8 @@ fit_canvas_to_selection(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to fit canvas to.")); return false; } - boost::optional<Geom::Rect> const bbox(desktop->selection->bounds()); - if (bbox && !bbox->isEmpty()) { + Geom::OptRect const bbox(desktop->selection->bounds()); + if (bbox) { doc->fitToRect(*bbox); return true; } else { @@ -2899,8 +2899,8 @@ fit_canvas_to_drawing(SPDocument *doc) sp_document_ensure_up_to_date(doc); SPItem const *const root = SP_ITEM(doc->root); - boost::optional<Geom::Rect> const bbox(root->getBounds(sp_item_i2r_affine(root))); - if (bbox && !bbox->isEmpty()) { + Geom::OptRect const bbox(root->getBounds(sp_item_i2r_affine(root))); + if (bbox) { doc->fitToRect(*bbox); return true; } else { diff --git a/src/selection.cpp b/src/selection.cpp index 4ed6c0842..ea1c0053f 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -383,11 +383,11 @@ NRRect *Selection::bounds(NRRect *bbox, SPItem::BBoxType type) const return bbox; } -boost::optional<Geom::Rect> Selection::bounds(SPItem::BBoxType type) const +Geom::OptRect Selection::bounds(SPItem::BBoxType type) const { GSList const *items = const_cast<Selection *>(this)->itemList(); - boost::optional<Geom::Rect> bbox; + Geom::OptRect bbox; for ( GSList const *i = items ; i != NULL ; i = i->next ) { bbox = unify(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type)); } @@ -415,7 +415,7 @@ NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const { return bbox; } -boost::optional<Geom::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const { +Geom::OptRect Selection::boundsInDocument(SPItem::BBoxType type) const { NRRect r; return to_2geom(boundsInDocument(&r, type)->upgrade()); } @@ -430,7 +430,7 @@ boost::optional<Geom::Point> Selection::center() const { return first->getCenter(); } } - boost::optional<Geom::Rect> bbox = bounds(); + Geom::OptRect bbox = bounds(); if (bbox) { return bounds()->midpoint(); } else { @@ -479,7 +479,7 @@ std::vector<Geom::Point> Selection::getSnapPointsConvexHull(SnapPreferences cons cvh.add(*i); } - boost::optional<Geom::Rect> rHull = cvh.bounds(); + Geom::OptRect rHull = cvh.bounds(); if (rHull) { for ( unsigned i = 0 ; i < 4 ; ++i ) { pHull.push_back(rHull->corner(i)); diff --git a/src/selection.h b/src/selection.h index 88e8ae90d..f3ab8e1c1 100644 --- a/src/selection.h +++ b/src/selection.h @@ -243,7 +243,7 @@ public: /** @brief Returns the bounding rectangle of the selection */ NRRect *bounds(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** @brief Returns the bounding rectangle of the selection */ - boost::optional<Geom::Rect> bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; + Geom::OptRect bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** * @brief Returns the bounding rectangle of the selection @@ -257,7 +257,7 @@ public: * * \todo how is this different from bounds()? */ - boost::optional<Geom::Rect> boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; + Geom::OptRect boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** * @brief Returns the rotation/skew center of the selection diff --git a/src/seltrans.h b/src/seltrans.h index 64ced3dc5..9fafb5a76 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -131,9 +131,9 @@ private: SPItem::BBoxType _snap_bbox_type; - boost::optional<Geom::Rect> _bbox; - boost::optional<Geom::Rect> _approximate_bbox; - boost::optional<Geom::Rect> _geometric_bbox; + Geom::OptRect _bbox; + Geom::OptRect _approximate_bbox; + Geom::OptRect _geometric_bbox; gdouble _strokewidth; Geom::Matrix _current_relative_affine; diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp index 04f40929b..d7cafaed2 100644 --- a/src/shape-editor.cpp +++ b/src/shape-editor.cpp @@ -22,7 +22,7 @@ #include "desktop.h" #include "desktop-handles.h" #include "knotholder.h" -#include "live_effects/parameter/pointparam-knotholder.h" +#include "live_effects/parameter/point.h" #include "nodepath.h" #include "xml/node-event-vector.h" #include "preferences.h" @@ -75,7 +75,7 @@ void ShapeEditor::unset_item(SubType type, bool keep_knotholder) { } this->grab_node = -1; - sp_nodepath_destroy(this->nodepath); + delete this->nodepath; this->nodepath = NULL; } break; diff --git a/src/snap.cpp b/src/snap.cpp index e0c83ad36..ebce87c98 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -120,7 +120,7 @@ bool SnapManager::someSnapperMightSnap() const void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type, Geom::Point &p, bool first_point, - boost::optional<Geom::Rect> const &bbox_to_snap) const + Geom::OptRect const &bbox_to_snap) const { Inkscape::SnappedPoint const s = freeSnap(point_type, p, first_point, bbox_to_snap); s.getPoint(p); @@ -140,7 +140,7 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p, bool first_point, - boost::optional<Geom::Rect> const &bbox_to_snap) const + Geom::OptRect const &bbox_to_snap) const { if (!someSnapperMightSnap()) { return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); @@ -206,7 +206,7 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const Geom::Point const t_offset = from_2geom(t) + grid->origin; SnappedConstraints sc; // Only the first three parameters are being used for grid snappers - snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, TRUE, boost::optional<Geom::Rect>(), NULL, NULL); + snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, TRUE, Geom::OptRect(), NULL, NULL); // Find the best snap for this grid, including intersections of the grid-lines Inkscape::SnappedPoint s = findBestSnap(t_offset, sc, false); if (s.getSnapped() && (s.getDistance() < nearest_distance)) { @@ -240,7 +240,7 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp Geom::Point &p, Inkscape::Snapper::ConstraintLine const &constraint, bool first_point, - boost::optional<Geom::Rect> const &bbox_to_snap) const + Geom::OptRect const &bbox_to_snap) const { Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, constraint, first_point, bbox_to_snap); s.getPoint(p); @@ -262,7 +262,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P Geom::Point const &p, Inkscape::Snapper::ConstraintLine const &constraint, bool first_point, - boost::optional<Geom::Rect> const &bbox_to_snap) const + Geom::OptRect const &bbox_to_snap) const { if (!someSnapperMightSnap()) { return Inkscape::SnappedPoint(p, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); @@ -598,7 +598,7 @@ Inkscape::SnappedPoint SnapManager::freeSnapTranslation(Inkscape::SnapPreference Geom::Point const &pointer, Geom::Point const &tr) const { - return _snapTransformed(point_type, p, pointer, false, Geom::Point(), TRANSLATION, tr, Geom::Point(), Geom::X, false); + return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), TRANSLATION, tr, Geom::Point(0,0), Geom::X, false); } @@ -620,7 +620,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapTranslation(Inkscape::SnapPre Inkscape::Snapper::ConstraintLine const &constraint, Geom::Point const &tr) const { - return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(), Geom::X, false); + return _snapTransformed(point_type, p, pointer, true, constraint, TRANSLATION, tr, Geom::Point(0,0), Geom::X, false); } @@ -641,7 +641,7 @@ Inkscape::SnappedPoint SnapManager::freeSnapScale(Inkscape::SnapPreferences::Poi Geom::Scale const &s, Geom::Point const &o) const { - return _snapTransformed(point_type, p, pointer, false, Geom::Point(), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false); + return _snapTransformed(point_type, p, pointer, false, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, false); } @@ -664,7 +664,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapScale(Inkscape::SnapPreferenc Geom::Point const &o) const { // When constrained scaling, only uniform scaling is supported. - return _snapTransformed(point_type, p, pointer, true, Geom::Point(), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true); + return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), SCALE, Geom::Point(s[Geom::X], s[Geom::Y]), o, Geom::X, true); } @@ -689,7 +689,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapStretch(Inkscape::SnapPrefere Geom::Dim2 d, bool u) const { - return _snapTransformed(point_type, p, pointer, true, Geom::Point(), STRETCH, Geom::Point(s, s), o, d, u); + return _snapTransformed(point_type, p, pointer, true, Geom::Point(0,0), STRETCH, Geom::Point(s, s), o, d, u); } diff --git a/src/snap.h b/src/snap.h index 15b4bd095..05af0d202 100644 --- a/src/snap.h +++ b/src/snap.h @@ -56,12 +56,12 @@ public: void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type, Geom::Point &p, bool first_point = true, - boost::optional<Geom::Rect> const &bbox_to_snap = boost::optional<Geom::Rect>()) const; + Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p, bool first_point = true, - boost::optional<Geom::Rect> const &bbox_to_snap = boost::optional<Geom::Rect>() ) const; + Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const; Geom::Point multipleOfGridPitch(Geom::Point const &t) const; @@ -71,13 +71,13 @@ public: Geom::Point &p, Inkscape::Snapper::ConstraintLine const &constraint, bool first_point = true, - boost::optional<Geom::Rect> const &bbox_to_snap = boost::optional<Geom::Rect>()) const; + Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p, Inkscape::Snapper::ConstraintLine const &constraint, bool first_point = true, - boost::optional<Geom::Rect> const &bbox_to_snap = boost::optional<Geom::Rect>()) const; + Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; void guideSnap(Geom::Point &p, Geom::Point const &guide_normal) const; diff --git a/src/snapper.h b/src/snapper.h index 7ad548ab4..0c405fd2b 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -62,7 +62,7 @@ public: SnapPreferences::PointType const &/*t*/, Geom::Point const &/*p*/, bool const &/*first_point*/, - boost::optional<Geom::Rect> const &/*bbox_to_snap*/, + Geom::OptRect const &/*bbox_to_snap*/, std::vector<SPItem const *> const */*it*/, std::vector<Geom::Point> */*unselected_nodes*/) const {}; @@ -100,7 +100,7 @@ public: SnapPreferences::PointType const &/*t*/, Geom::Point const &/*p*/, bool const &/*first_point*/, - boost::optional<Geom::Rect> const &/*bbox_to_snap*/, + Geom::OptRect const &/*bbox_to_snap*/, ConstraintLine const &/*c*/, std::vector<SPItem const *> const */*it*/) const {}; diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp index 14305c8a9..fbc4a93ca 100644 --- a/src/sp-conn-end-pair.cpp +++ b/src/sp-conn-end-pair.cpp @@ -167,7 +167,7 @@ SPConnEndPair::getEndpoints(NR::Point endPts[]) const { for (unsigned h = 0; h < 2; ++h) { if ( h2attItem[h] ) { - boost::optional<Geom::Rect> bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h])); + Geom::OptRect bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h])); if (bbox) { endPts[h] = bbox->midpoint(); } else { diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp index c94e75f71..5776388c3 100644 --- a/src/sp-conn-end.cpp +++ b/src/sp-conn-end.cpp @@ -72,7 +72,7 @@ sp_conn_end_move_compensate(Geom::Matrix const */*mp*/, SPItem */*moved_item*/, *(path->curve->penultimate_point()) }; for (unsigned h = 0; h < 2; ++h) { - boost::optional<Geom::Rect> bbox = h2attItem[h]->getBounds(Geom::identity()); + Geom::OptRect bbox = h2attItem[h]->getBounds(Geom::identity()); if (!bbox) { if (updatePathRepr) { path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -115,7 +115,7 @@ sp_conn_end_move_compensate(Geom::Matrix const */*mp*/, SPItem */*moved_item*/, Geom::Rect otherpt_rect = Geom::Rect(other_endpt, other_endpt); Geom::Rect h2bbox_icoordsys[2] = { otherpt_rect, otherpt_rect }; - boost::optional<Geom::Rect> bbox = h2attItem[ind]->getBounds(NR::identity()); + Geom::OptRect bbox = h2attItem[ind]->getBounds(NR::identity()); if (!bbox) { if (updatePathRepr) { path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index e1284f61e..b6f510201 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -243,8 +243,17 @@ static void sp_genericellipse_set_shape(SPShape *shape) Geom::Matrix aff = Geom::Scale(rx, ry) * Geom::Translate(ellipse->cx.computed, ellipse->cy.computed); curve->transform(aff); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM (ellipse), curve); - sp_shape_set_curve_insync((SPShape *) ellipse, curve, TRUE); + /* Reset the shape'scurve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + sp_shape_set_curve_insync (shape, curve, TRUE); + if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) { + SPCurve *c_lpe = curve->copy(); + bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe); + if (success) { + sp_shape_set_curve_insync (shape, c_lpe, TRUE); + } + c_lpe->unref(); + } curve->unref(); } diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 83c13ca05..e0f9b3472 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -352,7 +352,7 @@ sp_flowtext_print(SPItem *item, SPPrintContext *ctx) NRRect pbox; sp_item_invoke_bbox(item, &pbox, Geom::identity(), TRUE); NRRect bbox; - boost::optional<Geom::Rect> bbox_maybe = sp_item_bbox_desktop(item); + Geom::OptRect bbox_maybe = sp_item_bbox_desktop(item); if (!bbox_maybe) { return; } @@ -577,6 +577,10 @@ SPFlowtext::getAsText() sp_repr_set_svg_double(span_tspan, "x", anchor_point[Geom::X]); // FIXME: this will pick up the wrong end of counter-directional runs if (set_y) sp_repr_set_svg_double(span_tspan, "y", anchor_point[Geom::Y]); + if (line_tspan->childCount() == 0) { + sp_repr_set_svg_double(line_tspan, "x", anchor_point[Geom::X]); // FIXME: this will pick up the wrong end of counter-directional runs + sp_repr_set_svg_double(line_tspan, "y", anchor_point[Geom::Y]); + } SPObject *source_obj = 0; void *rawptr = 0; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index d0338f369..2b42a855b 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -701,7 +701,7 @@ void CGroup::onModified(guint flags) { void CGroup::calculateBBox(NRRect *bbox, Geom::Matrix const &transform, unsigned const flags) { - boost::optional<Geom::Rect> dummy_bbox; + Geom::OptRect dummy_bbox; GSList *l = _group->childList(false, SPObject::ActionBBox); while (l) { @@ -836,7 +836,7 @@ sp_group_update_patheffect (SPLPEItem *lpeitem, bool write) for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); it++) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - if (lpeobj->get_lpe()) { + if (lpeobj && lpeobj->get_lpe()) { lpeobj->get_lpe()->doBeforeEffect(lpeitem); } } diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 3b0b1e054..90f84ae0a 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -38,7 +38,7 @@ sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation) void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale) { - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(item); + Geom::OptRect bbox = sp_item_bbox_desktop(item); if (bbox) { Geom::Translate const s(bbox->midpoint()); // use getCenter? sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * s.inverse() * scale * s); @@ -95,7 +95,7 @@ get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewid gdouble h1 = y1 - y0; gdouble r0 = strokewidth; - if (bbox.isEmpty()) { + if (bbox.hasZeroArea()) { Geom::Matrix move = Geom::Translate(x0 - bbox.min()[Geom::X], y0 - bbox.min()[Geom::Y]); return (move); // cannot scale from empty boxes at all, so only translate } @@ -158,7 +158,7 @@ get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewid } Geom::Rect -get_visual_bbox (boost::optional<Geom::Rect> const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) +get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) { g_assert(initial_geom_bbox); diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h index 884732abe..40bf0fa4e 100644 --- a/src/sp-item-transform.h +++ b/src/sp-item-transform.h @@ -10,7 +10,7 @@ void sp_item_skew_rel (SPItem *item, double skewX, double skewY); void sp_item_move_rel(SPItem *item, Geom::Translate const &tr); Geom::Matrix get_scale_transform_with_stroke (Geom::Rect const &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); -Geom::Rect get_visual_bbox (boost::optional<Geom::Rect> const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); +Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); #endif /* !SP_ITEM_TRANSFORM_H */ diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 99f543328..8868b7875 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -291,7 +291,7 @@ SPItem::setExplicitlyHidden(bool const val) { */ void SPItem::setCenter(Geom::Point object_centre) { - boost::optional<Geom::Rect> bbox = getBounds(sp_item_i2d_affine(this)); + Geom::OptRect bbox = getBounds(sp_item_i2d_affine(this)); if (bbox) { transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X]; if (fabs(transform_center_x) < 1e-5) // rounding error @@ -313,7 +313,7 @@ bool SPItem::isCenterSet() { } Geom::Point SPItem::getCenter() const { - boost::optional<Geom::Rect> bbox = getBounds(sp_item_i2d_affine(this)); + Geom::OptRect bbox = getBounds(sp_item_i2d_affine(this)); if (bbox) { return to_2geom(bbox->midpoint()) + Geom::Point (this->transform_center_x, this->transform_center_y); } else { @@ -642,14 +642,13 @@ sp_item_update(SPObject *object, SPCtx *ctx, guint flags) /* Update bounding box data used by filters */ if (item->style->filter.set && item->display) { - NRRect item_bbox; - sp_item_invoke_bbox(item, &item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); - boost::optional<Geom::Rect> i_bbox = item_bbox; + Geom::OptRect item_bbox; + sp_item_invoke_bbox(item, item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); SPItemView *itemview = item->display; do { if (itemview->arenaitem) - nr_arena_item_set_item_bbox(itemview->arenaitem, i_bbox); + nr_arena_item_set_item_bbox(itemview->arenaitem, item_bbox); } while ( (itemview = itemview->next) ); } @@ -725,22 +724,22 @@ sp_item_write(SPObject *const object, Inkscape::XML::Document *xml_doc, Inkscape * \return There is no guarantee that the return value will contain a rectangle. If this item does not have a boundingbox, it might well be empty. */ -boost::optional<Geom::Rect> SPItem::getBounds(Geom::Matrix const &transform, +Geom::OptRect SPItem::getBounds(Geom::Matrix const &transform, SPItem::BBoxType type, unsigned int /*dkey*/) const { - boost::optional<Geom::Rect> r; + Geom::OptRect r; sp_item_invoke_bbox_full(this, r, transform, type, TRUE); return r; } void -sp_item_invoke_bbox(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) +sp_item_invoke_bbox(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) { sp_item_invoke_bbox_full(item, bbox, transform, type, clear); } -// DEPRECATED to phase out the use of NRRect in favor of boost::optional<Geom::Rect> +// DEPRECATED to phase out the use of NRRect in favor of Geom::OptRect void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) { @@ -755,13 +754,13 @@ sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transf * function returns. If this item does not have a boundingbox, this might well be empty. */ void -sp_item_invoke_bbox_full(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) +sp_item_invoke_bbox_full(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) { g_assert(item != NULL); g_assert(SP_IS_ITEM(item)); if (clear) { - bbox = boost::optional<Geom::Rect>(); + bbox = Geom::OptRect(); } // TODO: replace NRRect by Geom::Rect, for all SPItemClasses, and for SP_CLIPPATH @@ -844,20 +843,20 @@ sp_item_invoke_bbox_full(SPItem const *item, boost::optional<Geom::Rect> &bbox, // or it has explicitely been set to be like this (e.g. in sp_shape_bbox) // When x0 > x1 or y0 > y1, the bbox is considered to be "nothing", although it has not been - // explicitely defined this way for NRRects (as opposed to boost::optional<Geom::Rect>) + // explicitely defined this way for NRRects (as opposed to Geom::OptRect) // So union bbox with nothing = do nothing, just return return; } - // Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty boost::optional<Geom::Rect>() + // Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty Geom::OptRect() // for any rectangle with zero area. The geometrical bbox of for example a vertical line - // would therefore be translated into empty boost::optional<Geom::Rect>() (see bug https://bugs.launchpad.net/inkscape/+bug/168684) - boost::optional<Geom::Rect> temp_bbox_new = Geom::Rect(Geom::Point(temp_bbox.x0, temp_bbox.y0), Geom::Point(temp_bbox.x1, temp_bbox.y1)); + // would therefore be translated into empty Geom::OptRect() (see bug https://bugs.launchpad.net/inkscape/+bug/168684) + Geom::OptRect temp_bbox_new = Geom::Rect(Geom::Point(temp_bbox.x0, temp_bbox.y0), Geom::Point(temp_bbox.x1, temp_bbox.y1)); bbox = Geom::unify(bbox, temp_bbox_new); } -// DEPRECATED to phase out the use of NRRect in favor of boost::optional<Geom::Rect> +// DEPRECATED to phase out the use of NRRect in favor of Geom::OptRect /** Calls \a item's subclass' bounding box method; clips it by the bbox of clippath, if any; and * unions the resulting bbox with \a bbox. If \a clear is true, empties \a bbox first. Passes the * transform and the flags to the actual bbox methods. Note that many of subclasses (e.g. groups, @@ -931,9 +930,9 @@ sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type) sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE, type); } -boost::optional<Geom::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type) +Geom::OptRect sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type) { - boost::optional<Geom::Rect> rect = boost::optional<Geom::Rect>(); + Geom::OptRect rect = Geom::OptRect(); sp_item_invoke_bbox(item, rect, sp_item_i2d_affine(item), TRUE, type); return rect; } @@ -945,7 +944,7 @@ static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Ink * We don't know what shape we could be dealing with here, so we'll just * return the corners of the bounding box */ - boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2d_affine(item)); + Geom::OptRect bbox = item->getBounds(sp_item_i2d_affine(item)); if (bbox) { Geom::Point p1, p2; @@ -1134,10 +1133,9 @@ sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) SP_OBJECT(mask)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } NR_ARENA_ITEM_SET_DATA(ai, item); - NRRect item_bbox; - sp_item_invoke_bbox(item, &item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); - boost::optional<Geom::Rect> i_bbox = item_bbox; - nr_arena_item_set_item_bbox(ai, i_bbox); + Geom::OptRect item_bbox; + sp_item_invoke_bbox(item, item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); + nr_arena_item_set_item_bbox(ai, item_bbox); } return ai; @@ -1740,7 +1738,7 @@ sp_item_convert_to_guides(SPItem *item) { SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(item, bbox_type); + Geom::OptRect bbox = sp_item_bbox_desktop(item, bbox_type); if (!bbox) { g_warning ("Cannot determine item's bounding box during conversion to guides.\n"); return; diff --git a/src/sp-item.h b/src/sp-item.h index cd0a376bb..1cc05eb25 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -155,7 +155,7 @@ struct SPItem : public SPObject { void raiseToTop(); void lowerToBottom(); - boost::optional<Geom::Rect> getBounds(Geom::Matrix const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const; + Geom::OptRect getBounds(Geom::Matrix const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const; sigc::connection _clip_ref_connection; sigc::connection _mask_ref_connection; @@ -214,9 +214,9 @@ struct SPItemClass { /* Methods */ -void sp_item_invoke_bbox(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); +void sp_item_invoke_bbox(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); -void sp_item_invoke_bbox_full(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear); +void sp_item_invoke_bbox_full(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear); void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) __attribute__ ((deprecated)); unsigned sp_item_pos_in_parent(SPItem *item); @@ -252,7 +252,7 @@ gint sp_item_event (SPItem *item, SPEvent *event); NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key); void sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); -boost::optional<Geom::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); +Geom::OptRect sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); Geom::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor); Geom::Matrix i2i_affine(SPObject const *src, SPObject const *dest); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 0fe02e01d..1939b2ec0 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -209,19 +209,17 @@ sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value) try { path_effect_ref->link(href.c_str()); } catch (Inkscape::BadURIException e) { - g_warning("BadURIException: %s", e.what()); + g_warning("BadURIException when trying to find LPE: %s", e.what()); path_effect_ref->unlink(); delete path_effect_ref; path_effect_ref = NULL; } - if (path_effect_ref && path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe()) { - lpeitem->path_effect_list->push_back(path_effect_ref); - } else { - // something has gone wrong in finding the right patheffect. For example when the specified LPE name does not exist. - path_effect_ref->unlink(); - delete path_effect_ref; - path_effect_ref = NULL; + lpeitem->path_effect_list->push_back(path_effect_ref); + if ( !(path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe()) ) { + // something has gone wrong in finding the right patheffect. + g_warning("Unknown LPE type specified, LPE stack effectively disabled"); + // keep the effect in the lpestack, so the whole stack is effectively disabled but maintained } } } @@ -300,9 +298,12 @@ sp_lpe_item_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape:: return repr; } -void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { - if (!lpeitem) return; - if (!curve) return; +/** + * returns true when LPE was successful. + */ +bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { + if (!lpeitem) return false; + if (!curve) return false; if (sp_lpe_item_has_path_effect(lpeitem) && sp_lpe_item_path_effects_enabled(lpeitem)) { for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) @@ -313,22 +314,22 @@ void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { * For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found. */ g_warning("sp_lpe_item_perform_path_effect - NULL lpeobj in list!"); - return; + return false; } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); if (!lpe) { /** \todo Investigate the cause of this. * Not sure, but I think this can happen when an unknown effect type is specified... */ - g_warning("sp_lpe_item_perform_path_effect - lpeobj without lpe!"); - return; + g_warning("sp_lpe_item_perform_path_effect - lpeobj with invalid lpe in the stack!"); + return false; } if (lpe->isVisible()) { if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished // yet, we don't alter the path - return; + return false; } // Groups have their doBeforeEffect called elsewhere @@ -345,10 +346,13 @@ void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, _("An exception occurred during execution of the Path Effect.") ); } + return false; } } } } + + return true; } /** diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index c5dc4048b..e9561c2c2 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -54,7 +54,7 @@ struct SPLPEItemClass { GType sp_lpe_item_get_type(); void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); -void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve); +bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve); void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, gchar *value, bool reset); void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj); void sp_lpe_item_replace_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * old_lpeobj, diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index a73c178c7..2b7c8bbc4 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -34,8 +34,6 @@ #include "desktop.h" #include "conn-avoid-ref.h" // for defaultConnSpacing. - -#define DEFAULTTOLERANCE 0.4 #define DEFAULTGRIDCOLOR 0x3f3fff25 #define DEFAULTGRIDEMPCOLOR 0x3f3fff60 #define DEFAULTGRIDEMPSPACING 5 @@ -113,8 +111,7 @@ static void sp_namedview_init(SPNamedView *nv) nv->guides = NULL; nv->viewcount = 0; nv->grids = NULL; - nv->snapindicator = false; - + nv->default_layer_id = 0; nv->connector_spacing = defaultConnSpacing; @@ -246,7 +243,6 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape: sp_object_read_attr(object, "inkscape:window-x"); sp_object_read_attr(object, "inkscape:window-y"); sp_object_read_attr(object, "inkscape:snap-global"); - sp_object_read_attr(object, "inkscape:snap-indicator"); sp_object_read_attr(object, "inkscape:snap-bbox"); sp_object_read_attr(object, "inkscape:snap-nodes"); sp_object_read_attr(object, "inkscape:snap-guide"); @@ -327,7 +323,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va break; case SP_ATTR_GRIDTOLERANCE: nv->gridtoleranceunit = &px; - nv->gridtolerance = DEFAULTTOLERANCE; + nv->gridtolerance = 10000; if (value) { sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->gridtolerance, &nv->gridtoleranceunit); } @@ -335,7 +331,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va break; case SP_ATTR_GUIDETOLERANCE: nv->guidetoleranceunit = &px; - nv->guidetolerance = DEFAULTTOLERANCE; + nv->guidetolerance = 20; if (value) { sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->guidetolerance, &nv->guidetoleranceunit); } @@ -343,7 +339,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va break; case SP_ATTR_OBJECTTOLERANCE: nv->objecttoleranceunit = &px; - nv->objecttolerance = DEFAULTTOLERANCE; + nv->objecttolerance = 20; if (value) { sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->objecttolerance, &nv->objecttoleranceunit); } @@ -458,10 +454,6 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va nv->snap_manager.snapprefs.setSnapEnabledGlobally(value ? sp_str_to_bool(value) : TRUE); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_INKSCAPE_SNAP_INDICATOR: - nv->snapindicator = (value) ? sp_str_to_bool (value) : TRUE; - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; case SP_ATTR_INKSCAPE_SNAP_BBOX: nv->snap_manager.snapprefs.setSnapModeBBox(value ? sp_str_to_bool(value) : FALSE); object->requestModified(SP_OBJECT_MODIFIED_FLAG); diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 3ed02bf59..5a9c2971f 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -51,8 +51,7 @@ struct SPNamedView : public SPObjectGroup { SnapManager snap_manager; GSList * grids; bool grids_visible; - bool snapindicator; - + SPUnit const *doc_units; SPUnit const *gridtoleranceunit; diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp index f45ed1283..4c3d5196e 100644 --- a/src/sp-object-repr.cpp +++ b/src/sp-object-repr.cpp @@ -60,26 +60,26 @@ #include "xml/repr.h" #include "sp-filter.h" #include "sp-gaussian-blur.h" -#include "sp-feblend.h" -#include "sp-fecolormatrix.h" -#include "sp-fecomponenttransfer.h" -#include "sp-fecomponenttransfer-funcnode.h" -#include "sp-fecomposite.h" -#include "sp-feconvolvematrix.h" -#include "sp-fediffuselighting.h" -#include "sp-fedistantlight.h" -#include "sp-fedisplacementmap.h" -#include "sp-feflood.h" -#include "sp-feimage.h" -#include "sp-femerge.h" -#include "sp-femorphology.h" -#include "sp-feoffset.h" -#include "sp-fepointlight.h" -#include "sp-fespecularlighting.h" -#include "sp-fespotlight.h" -#include "sp-fetile.h" -#include "sp-feturbulence.h" -#include "sp-femergenode.h" +#include "filters/blend.h" +#include "filters/colormatrix.h" +#include "filters/componenttransfer.h" +#include "filters/componenttransfer-funcnode.h" +#include "filters/composite.h" +#include "filters/convolvematrix.h" +#include "filters/diffuselighting.h" +#include "filters/distantlight.h" +#include "filters/displacementmap.h" +#include "filters/flood.h" +#include "filters/image.h" +#include "filters/merge.h" +#include "filters/morphology.h" +#include "filters/offset.h" +#include "filters/pointlight.h" +#include "filters/specularlighting.h" +#include "filters/spotlight.h" +#include "filters/tile.h" +#include "filters/turbulence.h" +#include "filters/mergenode.h" #include "live_effects/lpeobject.h" #include "sp-title.h" #include "sp-desc.h" diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index c91b0ad0d..faa2cf457 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -510,8 +510,8 @@ sp_offset_set_shape(SPShape *shape) theRes->ConvertToForme (orig, 1, originaux); SPItem *item = shape; - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (item); - if ( bbox && !bbox->isEmpty() ) { + Geom::OptRect bbox = sp_item_bbox_desktop (item); + if ( bbox ) { gdouble size = L2(bbox->dimensions()); gdouble const exp = NR::expansion(item->transform); if (exp != 0) diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 404612be3..51c3746c8 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -388,19 +388,17 @@ sp_path_update_patheffect(SPLPEItem *lpeitem, bool write) { SPShape * const shape = (SPShape *) lpeitem; SPPath * const path = (SPPath *) lpeitem; + Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape); if (path->original_curve) { - // if a path does not have an lpeitem applied, then reset the curve to the original_curve. - // This is very important for LPEs on groups to work properly! SPCurve *curve = path->original_curve->copy(); + /* if a path does not have an lpeitem applied, then reset the curve to the original_curve. + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ sp_shape_set_curve_insync(shape, curve, TRUE); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve); - SP_OBJECT(shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); // this might be optimized in future for the case when this path is in a group with lpe applied (and will therefore have its curve change again when the group LPE is applied) - curve->unref(); - if (write) { + bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve); + if (success && write) { // could also do SP_OBJECT(shape)->updateRepr(); but only the d attribute needs updating. - Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape); if ( shape->curve != NULL ) { gchar *str = sp_svg_write_path(shape->curve->get_pathvector()); repr->setAttribute("d", str); @@ -408,7 +406,19 @@ sp_path_update_patheffect(SPLPEItem *lpeitem, bool write) } else { repr->setAttribute("d", NULL); } + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + sp_shape_set_curve(shape, oldcurve, TRUE); + oldcurve->unref(); + } + } } + SP_OBJECT(shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + curve->unref(); } } diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 96ff50cda..711f2c408 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -226,7 +226,7 @@ sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_PATTERNTRANSFORM: { - NR::Matrix t; + Geom::Matrix t; if (value && sp_svg_transform_read (value, &t)) { pat->patternTransform = t; pat->patternTransform_set = TRUE; diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 2a23b1115..d3f357e76 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -276,7 +276,7 @@ sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags) if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { /* This is suboptimal, because changing parent style schedules recalculation */ /* But on the other hand - how can we know that parent does not tie style and transform */ - boost::optional<Geom::Rect> paintbox = SP_ITEM(object)->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); + Geom::OptRect paintbox = SP_ITEM(object)->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); for (SPItemView *v = SP_ITEM (shape)->display; v != NULL; v = v->next) { NRArenaShape * const s = NR_ARENA_SHAPE(v->arenaitem); if (flags & SP_OBJECT_MODIFIED_FLAG) { @@ -484,69 +484,40 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const & { SPShape const *shape = SP_SHAPE (item); if (shape->curve) { - - NRRect cbbox; - - Geom::Rect geombbox = bounds_exact_transformed(shape->curve->get_pathvector(), transform); - cbbox.x0 = geombbox[0][0]; - cbbox.y0 = geombbox[1][0]; - cbbox.x1 = geombbox[0][1]; - cbbox.y1 = geombbox[1][1]; - - if ((SPItem::BBoxType) flags != SPItem::GEOMETRIC_BBOX) { - - SPStyle* style=SP_OBJECT_STYLE (item); - if (!style->stroke.isNone()) { - double const scale = transform.descrim(); - if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord - double const width = MAX(0.125, style->stroke_width.computed * scale); - if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { - cbbox.x0-=0.5*width; - cbbox.x1+=0.5*width; - cbbox.y0-=0.5*width; - cbbox.y1+=0.5*width; - } - } - } - - // Union with bboxes of the markers, if any - if (sp_shape_has_markers (shape)) { - /* TODO: make code prettier: lots of variables can be taken out of the loop! */ - Geom::PathVector const & pathv = shape->curve->get_pathvector(); - for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { - if ( shape->marker[SP_MARKER_LOC_START] ) { - SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_START]); - SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_START])); - - Geom::Matrix tr(sp_shape_marker_get_transform_at_start(path_it->front())); - - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { - tr = Geom::Scale(style->stroke_width.computed) * tr; + Geom::OptRect geombbox = bounds_exact_transformed(shape->curve->get_pathvector(), transform); + if (geombbox) { + NRRect cbbox; + cbbox.x0 = (*geombbox)[0][0]; + cbbox.y0 = (*geombbox)[1][0]; + cbbox.x1 = (*geombbox)[0][1]; + cbbox.y1 = (*geombbox)[1][1]; + + if ((SPItem::BBoxType) flags != SPItem::GEOMETRIC_BBOX) { + + SPStyle* style=SP_OBJECT_STYLE (item); + if (!style->stroke.isNone()) { + double const scale = transform.descrim(); + if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord + double const width = MAX(0.125, style->stroke_width.computed * scale); + if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { + cbbox.x0-=0.5*width; + cbbox.x1+=0.5*width; + cbbox.y0-=0.5*width; + cbbox.y1+=0.5*width; } - - // total marker transform - tr = marker_item->transform * marker->c2p * tr * transform; - - // get bbox of the marker with that transform - NRRect marker_bbox; - sp_item_invoke_bbox (marker_item, &marker_bbox, from_2geom(tr), true); - // union it with the shape bbox - nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); } + } - if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) { - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - while (curve_it2 != path_it->end_default()) - { - /* Put marker between curve_it1 and curve_it2. - * Loop to end_default (so including closing segment), because when a path is closed, - * there should be a midpoint marker between last segment and closing straight line segment */ - - SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_MID]); - SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_MID])); + // Union with bboxes of the markers, if any + if (sp_shape_has_markers (shape)) { + /* TODO: make code prettier: lots of variables can be taken out of the loop! */ + Geom::PathVector const & pathv = shape->curve->get_pathvector(); + for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { + if ( shape->marker[SP_MARKER_LOC_START] ) { + SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_START]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_START])); - Geom::Matrix tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2)); + Geom::Matrix tr(sp_shape_marker_get_transform_at_start(path_it->front())); if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { tr = Geom::Scale(style->stroke_width.computed) * tr; @@ -560,45 +531,74 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const & sp_item_invoke_bbox (marker_item, &marker_bbox, from_2geom(tr), true); // union it with the shape bbox nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); - - ++curve_it1; - ++curve_it2; } - } - if ( shape->marker[SP_MARKER_LOC_END] ) { - SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_END]); - SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_END])); + if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) { + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + while (curve_it2 != path_it->end_default()) + { + /* Put marker between curve_it1 and curve_it2. + * Loop to end_default (so including closing segment), because when a path is closed, + * there should be a midpoint marker between last segment and closing straight line segment */ - /* Get reference to last curve in the path. - * For moveto-only path, this returns the "closing line segment". */ - unsigned int index = path_it->size_default(); - if (index > 0) { - index--; - } - Geom::Curve const &lastcurve = (*path_it)[index]; + SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_MID]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_MID])); + + Geom::Matrix tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2)); + + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + tr = Geom::Scale(style->stroke_width.computed) * tr; + } - Geom::Matrix tr = sp_shape_marker_get_transform_at_end(lastcurve); + // total marker transform + tr = marker_item->transform * marker->c2p * tr * transform; - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { - tr = Geom::Scale(style->stroke_width.computed) * tr; + // get bbox of the marker with that transform + NRRect marker_bbox; + sp_item_invoke_bbox (marker_item, &marker_bbox, from_2geom(tr), true); + // union it with the shape bbox + nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + + ++curve_it1; + ++curve_it2; + } } - // total marker transform - tr = marker_item->transform * marker->c2p * tr * transform; + if ( shape->marker[SP_MARKER_LOC_END] ) { + SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_END]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_END])); + + /* Get reference to last curve in the path. + * For moveto-only path, this returns the "closing line segment". */ + unsigned int index = path_it->size_default(); + if (index > 0) { + index--; + } + Geom::Curve const &lastcurve = (*path_it)[index]; + + Geom::Matrix tr = sp_shape_marker_get_transform_at_end(lastcurve); - // get bbox of the marker with that transform - NRRect marker_bbox; - sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true); - // union it with the shape bbox - nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + tr = Geom::Scale(style->stroke_width.computed) * tr; + } + + // total marker transform + tr = marker_item->transform * marker->c2p * tr * transform; + + // get bbox of the marker with that transform + NRRect marker_bbox; + sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true); + // union it with the shape bbox + nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + } } } } - } - // copy our bbox to the variable we're given - *bbox = cbbox; + // copy our bbox to the variable we're given + *bbox = cbbox; + } } } @@ -744,7 +744,7 @@ sp_shape_show (SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int NRArenaShape * const s = NR_ARENA_SHAPE(arenaitem); nr_arena_shape_set_style(s, object->style); nr_arena_shape_set_path(s, shape->curve, false); - boost::optional<Geom::Rect> paintbox = item->getBounds(Geom::identity()); + Geom::OptRect paintbox = item->getBounds(Geom::identity()); if (paintbox) { s->setPaintBox(*paintbox); } diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 9a3708d4b..23233d04e 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -455,8 +455,17 @@ sp_spiral_set_shape (SPShape *shape) sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0), darray, hat1, hat2, &t); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM (spiral), c); - sp_shape_set_curve_insync ((SPShape *) spiral, c, TRUE); + /* Reset the shape'scurve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + sp_shape_set_curve_insync (shape, c, TRUE); + if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) { + SPCurve *c_lpe = c->copy(); + bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe); + if (success) { + sp_shape_set_curve_insync (shape, c_lpe, TRUE); + } + c_lpe->unref(); + } c->unref(); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index f5649e19f..79bdc4650 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -491,8 +491,18 @@ sp_star_set_shape (SPShape *shape) } c->closepath(); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM (star), c); - sp_shape_set_curve_insync (SP_SHAPE (star), c, TRUE); + + /* Reset the shape'scurve to the "original_curve" + * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ + sp_shape_set_curve_insync (shape, c, TRUE); + if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) { + SPCurve *c_lpe = c->copy(); + bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe); + if (success) { + sp_shape_set_curve_insync (shape, c_lpe, TRUE); + } + c_lpe->unref(); + } c->unref(); } diff --git a/src/splivarot.cpp b/src/splivarot.cpp index a3a4ce59f..eb01e625a 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1648,7 +1648,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, bool didSomething = false; - boost::optional<Geom::Rect> selectionBbox = selection->bounds(); + Geom::OptRect selectionBbox = selection->bounds(); if (!selectionBbox) { return false; } @@ -1669,7 +1669,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, continue; if (simplifyIndividualPaths) { - boost::optional<Geom::Rect> itemBbox = item->getBounds(sp_item_i2d_affine(item)); + Geom::OptRect itemBbox = item->getBounds(sp_item_i2d_affine(item)); if (itemBbox) { simplifySize = L2(itemBbox->dimensions()); } else { diff --git a/src/streams-gzip.cpp b/src/streams-gzip.cpp deleted file mode 100644 index c77e7162b..000000000 --- a/src/streams-gzip.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * IO layer : gzip streambuf and streams - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#include <cstring> -#include <string> -#include <string.h> - -#include "streams-gzip.h" - -namespace Inkscape { - -//With some inpsiration and code from libgsf, fastjar, libpng and RFC 1952 - -static int const GZIP_IS_ASCII = 0x01; //file contains text -static int const GZIP_HEADER_CRC = 0x02; //there is a CRC in the header -static int const GZIP_EXTRA_FIELD = 0x04; //there is an 'extra' field -static int const GZIP_ORIGINAL_NAME = 0x08; //the original is stored -static int const GZIP_HAS_COMMENT = 0x10; //There is a comment in the header -static unsigned int const GZIP_HEADER_FLAGS = (GZIP_IS_ASCII - |GZIP_HEADER_CRC - |GZIP_EXTRA_FIELD - |GZIP_ORIGINAL_NAME - |GZIP_HAS_COMMENT); - -/** - * GZipBuffer - */ - -void GZipBuffer::consume_header() throw(GZipHeaderException) -{ - unsigned int flags; - guint8 data[4]; - - try { - _urihandle->read(data, 4); - check_signature(data); - check_flags(data); - flags = data[3]; - _urihandle->read(data, 4); - //get_modification_time() - _urihandle->read(data, 1); - //check_extra_flags(); - _urihandle->read(data, 1); - //check_OS(); - - if (flags & GZIP_EXTRA_FIELD) { - get_extrafield(); - } - if (flags & GZIP_ORIGINAL_NAME) { - get_filename(); - } - if (flags & GZIP_HAS_COMMENT) { - get_comment(); - } - if (flags & GZIP_HEADER_CRC) { - get_crc(); - } - } - catch(std::exception& e) { - throw GZipHeaderException(); - } -} - -void GZipBuffer::check_signature(guint8 *data) throw(GZipHeaderException) -{ - guint8 const signature[2] = {0x1f, 0x8b}; - if (memcmp(data, signature, sizeof(signature)) != 0) - throw GZipHeaderException(); -} - -void GZipBuffer::check_flags(guint8 *data) throw(GZipHeaderException) -{ - unsigned int flags = data[3]; - if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0) - throw GZipHeaderException(); -} - -gchar *GZipBuffer::get_filename() -{ -#ifdef DEBUG_STREAMS - std::cout<<"Filename is "; -#endif - return read_string(); -} - -gchar *GZipBuffer::get_comment() -{ -#ifdef DEBUG_STREAMS - std::cout<<"Comment is "<<std::endl; -#endif - return read_string(); -} - -guint16 GZipBuffer::get_crc() -{ - guint16 buf; - _urihandle->read(&buf, 2); - return buf; -} - -void GZipBuffer::get_extrafield() -{ - guint8 length_data[2]; - _urihandle->read(length_data, 2); - unsigned int const length = length_data[0] | (length_data[1] << 8); - guint8 *data = new guint8[length]; - _urihandle->read(data, length); -} - -gchar *GZipBuffer::read_string() throw(GZipHeaderException) -{ - GByteArray *gba = g_byte_array_new(); - try { - guint8 byte[1]; - do { - _urihandle->read(byte, 1); - g_byte_array_append(gba, byte, sizeof(byte)); -#ifdef DEBUG_STREAMS - std::cout <<(char)*byte; -#endif - } while (*byte != 0); - } catch (std::exception& e) { - g_byte_array_free(gba, TRUE); - throw GZipHeaderException(); - } -#ifdef DEBUG_STREAMS - std::cout<<std::endl; -#endif - gchar *ret = (gchar *)gba->data; - g_byte_array_free(gba, FALSE); - return ret; -} - -} // 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/streams-gzip.h b/src/streams-gzip.h deleted file mode 100644 index ace1b884d..000000000 --- a/src/streams-gzip.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * IO layer : gzip streambuf and streams - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#ifndef __STREAMS_GZIP_H_ -#define __STREAMS_GZIP_H_ - -#include "streams-zlib.h" - -namespace Inkscape { - -class GZipHeaderException : public ZlibBufferException -{ -public: - const char *what() const throw() { return "Invalid gzip file"; } -}; - -/** - * GZipBuffer - */ - -class GZipBuffer : public ZlibBuffer -{ -public: - - GZipBuffer(URIHandle& urih) //throws GZipHeaderException - : ZlibBuffer(urih) - { consume_header(); } - ~GZipBuffer() {} - -private: - - void consume_header() throw(GZipHeaderException); - void check_signature(guint8 *data) throw(GZipHeaderException); - void check_flags(guint8 *data) throw(GZipHeaderException); - gchar *get_filename(); - gchar *get_comment(); - guint16 get_crc(); - void get_extrafield(); - gchar *read_string() throw(GZipHeaderException); - - GZipBuffer& operator=(GZipBuffer const& rhs); - GZipBuffer(GZipBuffer const& rhs); - -}; - -} // namespace Inkscape -#endif // header guard - -/* - 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/streams-handles.cpp b/src/streams-handles.cpp deleted file mode 100644 index 9c6e861f8..000000000 --- a/src/streams-handles.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * IO layer : handles for URIs - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#include "streams-handles.h" -#include "uri.h" - -#include <iostream> - -namespace Inkscape { - -/** - * FileHandle - */ - -int FileHandle::open(URI const& uri, char const* mode) -{ - if (sys_open(uri, mode) == 0) - return 0; - else - return 1; -} - -FILE *FileHandle::sys_open(URI const& uri, char const* mode) -{ - gchar *filename = uri.toNativeFilename(); - - if ((fp = std::fopen(filename, mode)) == 0) { - error("fopen"); - } -#ifdef DEBUG_STREAMS - std::cout<<"file opened fp="<<fp<<std::endl; -#endif - return fp; -} - -void FileHandle::close() -{ - sys_close(); -} - -void FileHandle::sys_close() -{ - fclose(fp); -} - -int FileHandle::read(void *buf, int buflen) -{ - return sys_read(buf, buflen); -} - -int FileHandle::sys_read (void *buf, int buflen) throw(ReadException) -{ - int nbytes = 0; - if ((nbytes = std::fread(buf, 1, buflen, fp)) < 0) { - if (ferror(fp)) { - error("fread"); - throw ReadException(); - } - } - if (nbytes == 0) - return EOF; - else - return nbytes; -} - -int FileHandle::write (void const *buf, int buflen) -{ - return sys_write(buf, buflen); -} - -int FileHandle::sys_write (void const *buf, int buflen) throw(WriteException) -{ - int nbytes = 0; - if ((nbytes = std::fwrite(buf, 1, buflen, fp)) < 0) { - error("fwrite"); - throw WriteException(); - } - - return nbytes; -} - -int FileHandle::seek(long offset, int whence) -{ - return sys_seek(offset, whence); -} - -int FileHandle::sys_seek(long offset, int whence) -{ - int result; - if ((result = fseek(fp, offset, whence)) < 0) { - error("fseek"); - } - return result; -} -void FileHandle::error(char const *errstr) -{ - std::cerr<<"error FileHandle: "<<errstr<<std::endl; -} - -} // 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/streams-handles.h b/src/streams-handles.h deleted file mode 100644 index 1dad4a266..000000000 --- a/src/streams-handles.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * IO layer : handles for URIs - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#ifndef __STREAM_HANDLES_H_ -#define __STREAM_HANDLES_H_ - -#include <stdio.h> -#include <exception> - -#include "forward.h" - -namespace Inkscape { - -/** - * URIHandle (Abstract class) - */ - -class URIHandle -{ -public: - virtual ~URIHandle() {} - virtual int read (void *buf, int buflen) = 0; - virtual int write (void const *buf, int buflen) = 0; - virtual void close() = 0; - -protected: - - virtual int sys_read (void *buf, int buflen) = 0; - virtual int sys_write (void const *buf, int buflen) = 0; - virtual void sys_close() = 0; - virtual void error(char const *errstr) = 0; - -}; - -/** - * FileHandle - */ - -class IOException : public std::exception {}; - -class ReadException : public IOException -{ -public: - const char *what() const throw() { return "error read"; } -}; - -class WriteException : public IOException -{ -public: - const char *what() const throw() { return "error write"; } -}; - -class FileHandle : public URIHandle -{ -public: - FileHandle() : fp(0) {} - virtual ~FileHandle() { if (fp) sys_close(); }; - virtual int open(URI const& uri, char const* mode); - virtual void close(); - virtual int read (void *buf, int buflen); - virtual int write (void const *buf, int buflen); - virtual int seek (long offset, int whence); -protected: - - virtual FILE *sys_open(URI const& uri, char const* mode); - virtual void sys_close(); - virtual int sys_read(void *buf, int buflen) throw(ReadException); - virtual int sys_write(void const *buf, int buflen) throw(WriteException); - virtual int sys_seek(long offset, int whence); - virtual void error(char const *errstr); - FILE *get_fp() { return fp; } - -private: - FILE *fp; -}; - -/* - class SocketHandle : public URIHandle - { - // ... - }; -*/ -} -#endif - -/* - 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/streams-jar.cpp b/src/streams-jar.cpp deleted file mode 100644 index e597822e9..000000000 --- a/src/streams-jar.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include <vector> -#include "streams-jar.h" - -namespace Inkscape { - -const int LOC_EXTRA = 6; // extra bytes -const int LOC_COMP = 8; // compression method -const int LOC_CSIZE = 18; // compressed size -const int LOC_FNLEN = 26; // filename length -const int LOC_EFLEN = 28; // extra-field length - -void JarBuffer::consume_header() throw(JarHeaderException) -{ - try { - guint8 data[30]; - _urihandle->read(data, 4); - check_signature(data); - _urihandle->read(data+4, 26); - compressed_size = compressed_left = unpack_4bytes(data, LOC_CSIZE); - eflen = unpack_2bytes(data, LOC_EFLEN); - flags = unpack_2bytes(data, LOC_EXTRA); - method = unpack_2bytes(data, LOC_COMP); - -#ifdef DEBUG_STREAMS - std::printf("Compressed size is %u\n", compressed_size); - std::printf("Extra field length is %hu\n", eflen); - std::printf("Flags are %#hx\n", flags); - std::printf("Compression method is %#hx\n", method); -#endif - } - catch (std::exception& e) { - throw JarHeaderException(); - } -} - -void JarBuffer::check_signature(guint8 *data) throw(JarHeaderException) -{ - guint32 signature = unpack_4bytes(data, 0); - -#ifdef DEBUG_STREAMS - std::printf("signature is %x\n", signature); -#endif - - if (signature == 0x08074b50) { - _urihandle->read(data, 12); - } else if (signature != 0x02014b50 && signature != 0x04034b50) { - throw JarHeaderException(); - } -} - -void JarBuffer::reset()//resets zlib and buffer (also skips archived directories) -{ - bool do_reset = false; - while (compressed_left == 0) { - consume_header(); - do_reset = true; - } - - if (do_reset) { - reset_inflation(); - setg(eback(), eback(), eback()); - } -} - -int JarBuffer::consume_and_inflate() -{ - int nbytes; - - reset(); - - nbytes = compressed_left > BUFSIZE_STREAM ? BUFSIZE_STREAM - : compressed_left; - - if (is_compressed()) - return consume_compressed(nbytes); - else - return consume_uncompressed(nbytes); -} - -int JarBuffer::consume_compressed(int nbytes) -{ - int ret=do_consume_and_inflate(nbytes); - - if ( ret == EOF && eflen > 0 ) { - std::vector<guint8> efbuf(eflen); - _urihandle->read(&efbuf[0], eflen); - return 1; - } - - return ret; -} - -int JarBuffer::consume_uncompressed(int nbytes) -{ - std::vector<guint8> data(nbytes); - int consumed=consume(&data[0], nbytes); - if ( consumed != EOF ) { - copy_to_get(&data[0], consumed); - compressed_left -= consumed; - } - return consumed; -} - -GByteArray *JarBuffer::inflate(guint8 *data, const int nbytes) -{ - GByteArray *gba = do_inflate(data, nbytes); - compressed_left -= nbytes; - return gba; -} - -guint32 JarBuffer::unpack_4bytes(guint8 *data, const int offset) -{ - return ((guint32)data[offset] - + (((guint32)data[offset + 1]) << 8) - + (((guint32)data[offset + 2]) << 16) - + (((guint32)data[offset + 3]) << 24)); -} - -guint16 JarBuffer::unpack_2bytes(guint8 *data, int offset) -{ - return ((guint16)data[offset] + (((guint16)data[offset + 1]) << 8)); -} - -} // 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/streams-jar.h b/src/streams-jar.h deleted file mode 100644 index cba69096e..000000000 --- a/src/streams-jar.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __STREAMS_JAR_H_ -#define __STREAMS_JAR_H_ - -#include "streams-zlib.h" - -namespace Inkscape { - -//#define DEBUG_STREAMS 1; - -class JarHeaderException -{ -public: - const char *what() const throw() { return "Invalid file header in jar"; } -}; - -/** - * JarBuffer - */ - -class JarBuffer : public ZlibBuffer -{ -public: - - JarBuffer(URIHandle& urih) //throws JarHeaderException - : ZlibBuffer(urih), compressed_size(0), compressed_left(0), method(0), - flags(0) - { consume_header(); } - virtual ~JarBuffer() {} - -protected: - - virtual void consume_header() throw(JarHeaderException); - virtual void check_signature(guint8 *data) throw(JarHeaderException); - virtual unsigned int get_compressed_size() const { return compressed_size; } - virtual unsigned int get_compressed_left() const { return compressed_left; } - virtual GByteArray *inflate(guint8 *data, int nbytes); - virtual int consume_and_inflate(); - virtual void reset(); - virtual bool is_compressed() const { return (method == 8 || flags & 0x0008);} - virtual int consume_compressed(int nbytes); - virtual int consume_uncompressed(int nbytes); - guint32 unpack_4bytes(guint8 *data, const int offset); - guint16 unpack_2bytes(guint8 *data, const int offset); - -private: - - JarBuffer& operator=(JarBuffer const& rhs); - JarBuffer(JarBuffer const& rhs); - - guint32 compressed_size; - guint32 compressed_left; - guint16 method; - guint16 flags; - guint16 eflen; -}; - -} // namespace Inkscape -#endif // header guard - -/* - 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/streams-zlib.cpp b/src/streams-zlib.cpp deleted file mode 100644 index 2d5fae01e..000000000 --- a/src/streams-zlib.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * IO layer : zlib streambuf - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#include <cstring> -#include <string> -#include <string.h> -#include <vector> -#include "streams-zlib.h" - -namespace Inkscape { - -/** - * ZlibBuffer - */ - -ZlibBuffer::ZlibBuffer(URIHandle& urih) - : _urihandle(&urih), _putsize(BUFSIZE_STREAM), _getsize(BUFSIZE_STREAM) -{ - init_inflation(); -} - -int ZlibBuffer::allocate_buffers() -{ - if (!eback()) { - char *buf = new char[_getsize + _putsize]; - setg(buf, buf , buf); - buf += _getsize; - setp(buf, buf + _putsize); - return 1; - } - return 0; -} - -int ZlibBuffer::reallocate_buffers(int new_getsize, int new_putsize) -{ - char *new_buffer = new char[new_getsize + new_putsize]; - - std::memcpy(new_buffer, eback(), _getsize); - std::memcpy(new_buffer, eback() + _getsize, _putsize); - - setg(new_buffer, new_buffer + (gptr() - eback()), - new_buffer + new_getsize); - new_buffer += new_getsize; - setp(new_buffer, new_buffer + new_putsize); - - _getsize = new_getsize; - _putsize = new_putsize; - - return 1; -} - -int ZlibBuffer::underflow() -{ - if (eback() == 0 && allocate_buffers() == 0) - return EOF; - - if (consume_and_inflate() == EOF) - return EOF; - - return *(unsigned char *)gptr(); -} - -int ZlibBuffer::overflow(int c) -{ - if (c == EOF) - return flush_output(); - - if (pbase() == 0 && allocate_buffers() == 0) - return EOF; - - if (pptr() >= epptr() && - flush_output() == EOF) - return EOF; - - putchar(c); - - if (pptr() >= epptr() && - flush_output() == EOF) - return EOF; - - return c; -} - -int ZlibBuffer::consume(guint8 *buf, int nbytes) -{ - return do_consume(buf, nbytes); -} - -int ZlibBuffer::do_consume(guint8 *buf, int nbytes) -{ - nbytes = _urihandle->read(buf, nbytes); - - if (nbytes == EOF) - return EOF; - else if (nbytes == 0) - return EOF; - - return nbytes; -} - -int ZlibBuffer::do_consume_and_inflate(int nbytes) -{ - std::vector<guint8> buf(nbytes); - - int ret=consume(&buf[0], nbytes); - - if ( ret != EOF ) { - ret = 1; - GByteArray *gba = inflate(&buf[0], nbytes); - copy_to_get(gba->data, gba->len); - g_byte_array_free(gba, TRUE); - } - - return ret; -} - -int ZlibBuffer::consume_and_inflate() -{ - return do_consume_and_inflate(BUFSIZE_STREAM); -} - -int ZlibBuffer::flush_output() -{ - if (pptr() <= pbase()) - return 0; - int len = pptr() - pbase(); - int nbytes = _urihandle->write(pbase(), len); - setp(pbase(), pbase() + BUFSIZE_STREAM); - if (len == nbytes) - return 0; - else - return EOF; -} - -void ZlibBuffer::init_inflation() throw(ZlibBufferException) -{ - memset(&_zs, 0, sizeof(z_stream)); - - _zs.zalloc = Z_NULL; - _zs.zfree = Z_NULL; - _zs.opaque = Z_NULL; - - if(inflateInit2(&_zs, -15) != Z_OK) { - throw ZlibBufferException(); - } - -} - -void ZlibBuffer::reset_inflation() throw(ZlibBufferException) -{ - if (inflateReset(&_zs) != Z_OK) - throw ZlibBufferException(); -} - -GByteArray *ZlibBuffer::inflate(guint8 *in_buffer, int nbytes) -{ - return do_inflate(in_buffer, nbytes); -} - -GByteArray *ZlibBuffer::do_inflate(guint8 *data, int nbytes) -{ - GByteArray *gba = g_byte_array_new(); - guint8 out_buffer[BUFSIZE_STREAM]; - - _zs.avail_in = 0; - guint32 crc = crc32(0, Z_NULL, 0); - - if (!_zs.avail_in) { - _zs.avail_in = nbytes; - _zs.next_in = (Bytef *)data; - crc = crc32(crc, (Bytef *)data, _zs.avail_in); - } - do { - _zs.next_out = out_buffer; - _zs.avail_out = BUFSIZE_STREAM; - - int ret = ::inflate(&_zs, Z_NO_FLUSH); - if (BUFSIZE_STREAM != _zs.avail_out) { - unsigned int tmp_len = BUFSIZE_STREAM - _zs.avail_out; - g_byte_array_append(gba, out_buffer, tmp_len); - } - - if (ret == Z_STREAM_END) { - break; - } - if (ret != Z_OK) { - std::fprintf(stderr, "decompression error %d\n", ret); - break; - } - } while (_zs.avail_in); - - return gba; -} - -int ZlibBuffer::copy_to_get(guint8 *data, int nbytes) -{ - return do_copy_to_get(data, nbytes); -} - -int ZlibBuffer::do_copy_to_get(guint8 *data, int nbytes) -{ - if (nbytes + gptr() - eback() > _getsize) - reallocate_buffers(nbytes + gptr() - eback() + BUFSIZE_STREAM, - _putsize); - - std::memcpy(gptr(), data, nbytes); - setg(eback(), gptr(), gptr() + nbytes); - return 1; -} - -} // 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/streams-zlib.h b/src/streams-zlib.h deleted file mode 100644 index 6ab7405d1..000000000 --- a/src/streams-zlib.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * IO layer : zlib streambuf - * - * Authors: - * Johan Ceuppens <jceuppen at easynet dot be> - * - * Copyright (C) 2004 Johan Ceuppens - * - * Released under GNU LGPL, read the file 'COPYING.LIB' for more information - */ - -#ifndef __STREAMS_ZLIB_H_ -#define __STREAMS_ZLIB_H_ - -#include "streams-handles.h" - -#include <glib/gtypes.h> -#include <glib/garray.h> -#include <zlib.h> -#include <iostream> - -namespace Inkscape { - -class ZlibBufferException : public std::exception {}; - -// This is the initial buffersize for the stream and -// zipbuffers (the streambuffers expand as needed). -const unsigned int BUFSIZE_STREAM = 4096; - -/** - * ZlibBuffer - */ - -//TODO: unbuffered IO -class ZlibBuffer : public std::streambuf -{ -public: - - ZlibBuffer(URIHandle& urih); - virtual ~ZlibBuffer() {} - -protected: - - virtual int allocate_buffers(); - virtual int reallocate_buffers(int new_getsize, int new_putsize); - virtual int underflow(); - virtual int overflow(int c = EOF); - virtual int flush_output(); - - virtual void init_inflation() throw(ZlibBufferException); - virtual void reset_inflation() throw(ZlibBufferException); - virtual int consume_and_inflate(); - virtual int do_consume_and_inflate(int nbytes); - virtual int consume(guint8 *buf, int nbytes); - virtual int do_consume(guint8 *buf, int nbytes); - virtual GByteArray *inflate(guint8 *in_buffer, int nbytes); - virtual GByteArray *do_inflate(guint8 *in_buffer, int nbytes); - virtual int copy_to_get(guint8 *data, int nbytes); - virtual int do_copy_to_get(guint8 *data, int nbytes); - - URIHandle *_urihandle; - -private: - - ZlibBuffer& operator=(ZlibBuffer const& rhs); - ZlibBuffer(ZlibBuffer const& rhs); - - z_stream _zs; - int _putsize, _getsize;//sizes of in and out buffers - -}; - -class izstream : public std::istream { -public: - - explicit izstream(std::streambuf& sb) : std::istream(&sb) {} - ~izstream() { std::ios::init(0); } - - std::streambuf *rdbuf() { return std::ios::rdbuf(); } - std::streambuf *operator ->() { return rdbuf(); } - -}; - -} - -#endif - -/* - 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/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index bcc685e8a..1077f7e2f 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -37,18 +37,6 @@ bool sp_svg_transform_read(gchar const *str, Geom::Matrix *transform) { - NR::Matrix mat; - if (sp_svg_transform_read(str, &mat)) { - *transform = mat; - return true; - } else { - return false; - } -} - -bool -sp_svg_transform_read(gchar const *str, NR::Matrix *transform) -{ int idx; char keyword[32]; double args[6]; @@ -57,7 +45,7 @@ sp_svg_transform_read(gchar const *str, NR::Matrix *transform) if (str == NULL) return false; - NR::Matrix a(NR::identity()); + Geom::Matrix a(Geom::identity()); idx = 0; while (str[idx]) { @@ -117,7 +105,7 @@ sp_svg_transform_read(gchar const *str, NR::Matrix *transform) /* ok, have parsed keyword and args, now modify the transform */ if (!strcmp (keyword, "matrix")) { if (n_args != 6) return false; - a = (*NR_MATRIX_D_FROM_DOUBLE(args)) * a; + a = (*((Geom::Matrix *) &(args)[0])) * a; } else if (!strcmp (keyword, "translate")) { if (n_args == 1) { args[1] = 0; @@ -147,13 +135,13 @@ sp_svg_transform_read(gchar const *str, NR::Matrix *transform) } } else if (!strcmp (keyword, "skewX")) { if (n_args != 1) return false; - a = ( NR::Matrix(1, 0, + a = ( Geom::Matrix(1, 0, tan(args[0] * M_PI / 180.0), 1, 0, 0) * a ); } else if (!strcmp (keyword, "skewY")) { if (n_args != 1) return false; - a = ( NR::Matrix(1, tan(args[0] * M_PI / 180.0), + a = ( Geom::Matrix(1, tan(args[0] * M_PI / 180.0), 0, 1, 0, 0) * a ); @@ -263,17 +251,4 @@ gchar * sp_svg_transform_write(Geom::Matrix const *transform) { return sp_svg_transform_write(*transform); -} - -gchar * -sp_svg_transform_write(NR::Matrix const &transform) -{ - return sp_svg_transform_write((Geom::Matrix)transform); -} - -gchar * -sp_svg_transform_write(NR::Matrix const *transform) -{ - return sp_svg_transform_write(*transform); -} - +}
\ No newline at end of file diff --git a/src/svg/svg.h b/src/svg/svg.h index 0e9939bec..0eab21226 100644 --- a/src/svg/svg.h +++ b/src/svg/svg.h @@ -55,12 +55,9 @@ unsigned int sp_svg_length_read_ldd (const gchar *str, SVGLength::Unit *unit, do std::string sp_svg_length_write_with_units(SVGLength const &length); bool sp_svg_transform_read(gchar const *str, Geom::Matrix *transform); -bool sp_svg_transform_read(gchar const *str, NR::Matrix *transform); gchar *sp_svg_transform_write(Geom::Matrix const &transform); gchar *sp_svg_transform_write(Geom::Matrix const *transform); -gchar *sp_svg_transform_write(NR::Matrix const &transform); -gchar *sp_svg_transform_write(NR::Matrix const *transform); double sp_svg_read_percentage (const char * str, double def); diff --git a/src/text-context.cpp b/src/text-context.cpp index e277ff584..1dd5e4e82 100644 --- a/src/text-context.cpp +++ b/src/text-context.cpp @@ -446,7 +446,7 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve item_ungrouped = desktop->item_at_point(Geom::Point(event->button.x, event->button.y), TRUE); if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) { sp_canvas_item_show(tc->indicator); - boost::optional<Geom::Rect> ibbox = sp_item_bbox_desktop(item_ungrouped); + Geom::OptRect ibbox = sp_item_bbox_desktop(item_ungrouped); if (ibbox) { SP_CTRLRECT(tc->indicator)->setRectangle(*ibbox); } @@ -1609,7 +1609,7 @@ sp_text_context_update_cursor(SPTextContext *tc, bool scroll_to_see) SPItem *frame = SP_FLOWTEXT(tc->text)->get_frame (NULL); // first frame only if (frame) { sp_canvas_item_show(tc->frame); - boost::optional<Geom::Rect> frame_bbox = sp_item_bbox_desktop(frame); + Geom::OptRect frame_bbox = sp_item_bbox_desktop(frame); if (frame_bbox) { SP_CTRLRECT(tc->frame)->setRectangle(*frame_bbox); } @@ -1668,10 +1668,10 @@ sp_text_context_timeout(SPTextContext *tc) sp_canvas_item_show(tc->cursor); if (tc->phase) { tc->phase = 0; - sp_ctrlline_set_rgba32(SP_CTRLLINE(tc->cursor), 0xffffffff); + sp_ctrlline_set_rgba32(SP_CTRLLINE(tc->cursor), 0x000000ff); } else { tc->phase = 1; - sp_ctrlline_set_rgba32(SP_CTRLLINE(tc->cursor), 0x000000ff); + sp_ctrlline_set_rgba32(SP_CTRLLINE(tc->cursor), 0xffffffff); } } diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp index f8e88b53a..156ce0169 100644 --- a/src/tweak-context.cpp +++ b/src/tweak-context.cpp @@ -432,7 +432,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else { if (mode == TWEAK_MODE_MOVE) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; @@ -445,7 +445,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else if (mode == TWEAK_MODE_MOVE_IN_OUT) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; @@ -459,7 +459,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else if (mode == TWEAK_MODE_MOVE_JITTER) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double dp = g_random_double_range(0, M_PI*2); double dr = g_random_double_range(0, radius); @@ -474,7 +474,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else if (mode == TWEAK_MODE_SCALE) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; @@ -487,7 +487,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else if (mode == TWEAK_MODE_ROTATE) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; @@ -500,7 +500,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } else if (mode == TWEAK_MODE_MORELESS) { - boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; @@ -551,7 +551,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P // skip those paths whose bboxes are entirely out of reach with our radius - boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect bbox = item->getBounds(sp_item_i2doc_affine(item)); if (bbox) { bbox->expandBy(radius); if (!bbox->contains(p)) { @@ -925,7 +925,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, if (!style) { return false; } - boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item), + Geom::OptRect bbox = item->getBounds(sp_item_i2doc_affine(item), SPItem::GEOMETRIC_BBOX); if (!bbox) { return false; @@ -955,7 +955,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, if (this_force > 0.002) { if (do_blur) { - boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item), + Geom::OptRect bbox = item->getBounds(sp_item_i2doc_affine(item), SPItem::GEOMETRIC_BBOX); if (!bbox) { return did; diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index e76af958f..0dc4a1d5b 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -407,15 +407,15 @@ bool ClipboardManagerImpl::pasteSize(bool separately, bool apply_x, bool apply_y if (separately) { for (GSList *i = const_cast<GSList*>(selection->itemList()) ; i ; i = i->next) { SPItem *item = SP_ITEM(i->data); - boost::optional<Geom::Rect> obj_size = sp_item_bbox_desktop(item); - if ( !obj_size || obj_size->isEmpty() ) continue; + Geom::OptRect obj_size = sp_item_bbox_desktop(item); + if ( !obj_size ) continue; sp_item_scale_rel(item, _getScale(min, max, *obj_size, apply_x, apply_y)); } } // resize the selection as a whole else { - boost::optional<Geom::Rect> sel_size = selection->bounds(); - if ( sel_size && !sel_size->isEmpty() ) { + Geom::OptRect sel_size = selection->bounds(); + if ( sel_size ) { sp_selection_scale_relative(selection, sel_size->midpoint(), _getScale(min, max, *sel_size, apply_x, apply_y)); } @@ -571,7 +571,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) } } - boost::optional<Geom::Rect> size = selection->bounds(); + Geom::OptRect size = selection->bounds(); if (size) { sp_repr_set_point(_clipnode, "min", size->min()); sp_repr_set_point(_clipnode, "max", size->max()); @@ -786,7 +786,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDocument *clipdoc, bool in_place) selection->setReprList(pasted_objects); // Change the selection to the freshly pasted objects sp_document_ensure_up_to_date(target_document); // What does this do? - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); //In desktop coordinates + Geom::OptRect sel_bbox = selection->bounds(); //In desktop coordinates // PS: We could also have used the min/max corners calculated above, instead of selection->bounds() because // we know that after pasting the upper left corner of the selection will be aligend to the corresponding // page corner. Using the boundingbox of the selection is more foolproof though @@ -1083,17 +1083,14 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/) try { if (out == outlist.end() && target == "image/png") { - NRRect area; gdouble dpi = PX_PER_IN; guint32 bgcolor = 0x00000000; - area.x0 = SP_ROOT(_clipboardSPDoc->root)->x.computed; - area.y0 = SP_ROOT(_clipboardSPDoc->root)->y.computed; - area.x1 = area.x0 + sp_document_width (_clipboardSPDoc); - area.y1 = area.y0 + sp_document_height (_clipboardSPDoc); + Geom::Point origin (SP_ROOT(_clipboardSPDoc->root)->x.computed, SP_ROOT(_clipboardSPDoc->root)->y.computed); + Geom::Rect area = Geom::Rect(origin, origin + sp_document_dimensions(_clipboardSPDoc)); - unsigned long int width = (unsigned long int) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); - unsigned long int height = (unsigned long int) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); + unsigned long int width = (unsigned long int) (area.width() * dpi / PX_PER_IN + 0.5); + unsigned long int height = (unsigned long int) (area.height() * dpi / PX_PER_IN + 0.5); // read from namedview Inkscape::XML::Node *nv = sp_repr_lookup_name (_clipboardSPDoc->rroot, "sodipodi:namedview"); @@ -1102,7 +1099,7 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/) if (nv && nv->attribute("inkscape:pageopacity")) bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0)); - sp_export_png_file(_clipboardSPDoc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, NULL); + sp_export_png_file(_clipboardSPDoc, filename, area, width, height, dpi, dpi, bgcolor, NULL, NULL, true, NULL); } else { diff --git a/src/ui/dialog/CMakeLists.txt b/src/ui/dialog/CMakeLists.txt index abdfa4dd8..5a0d6a08e 100644 --- a/src/ui/dialog/CMakeLists.txt +++ b/src/ui/dialog/CMakeLists.txt @@ -9,6 +9,7 @@ ENDIF(WIN32) SET(ui_dialog_SRC aboutbox.cpp align-and-distribute.cpp +debug.cpp dialog.cpp dialog-manager.cpp dock-behavior.cpp @@ -33,6 +34,7 @@ print.cpp scriptdialog.cpp #session-player.cpp text-properties.cpp +tile.cpp tracedialog.cpp transformation.cpp tree-editor.cpp diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 638be2832..6c301ef40 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -6,18 +6,19 @@ ui/dialog/clean: rm -f ui/dialog/libuidialog.a $(ui_libuidialog_a_OBJECTS) ui_dialog_libuidialog_a_SOURCES = \ - ui/dialog/dialog-manager.cpp \ - ui/dialog/dialog-manager.h \ + ui/dialog/aboutbox.cpp \ + ui/dialog/aboutbox.h \ + ui/dialog/align-and-distribute.cpp \ + ui/dialog/align-and-distribute.h \ + ui/dialog/behavior.h \ + ui/dialog/debug.cpp \ + ui/dialog/debug.h \ ui/dialog/dialog.cpp \ ui/dialog/dialog.h \ - ui/dialog/panel-dialog.h \ - ui/dialog/behavior.h \ - ui/dialog/dock-behavior.h \ + ui/dialog/dialog-manager.cpp \ + ui/dialog/dialog-manager.h \ ui/dialog/dock-behavior.cpp \ - ui/dialog/floating-behavior.h \ - ui/dialog/floating-behavior.cpp \ - ui/dialog/align-and-distribute.cpp \ - ui/dialog/align-and-distribute.h \ + ui/dialog/dock-behavior.h \ ui/dialog/document-metadata.cpp \ ui/dialog/document-metadata.h \ ui/dialog/document-properties.cpp \ @@ -28,40 +29,43 @@ ui_dialog_libuidialog_a_SOURCES = \ ui/dialog/filedialog.h \ ui/dialog/filedialogimpl-gtkmm.cpp \ ui/dialog/filedialogimpl-gtkmm.h \ + ui/dialog/filedialogimpl-win32.cpp \ + ui/dialog/filedialogimpl-win32.h \ ui/dialog/fill-and-stroke.cpp \ ui/dialog/fill-and-stroke.h \ - ui/dialog/filter-effects-dialog.h \ ui/dialog/filter-effects-dialog.cpp \ + ui/dialog/filter-effects-dialog.h \ ui/dialog/find.cpp \ ui/dialog/find.h \ + ui/dialog/floating-behavior.cpp \ + ui/dialog/floating-behavior.h \ ui/dialog/inkscape-preferences.cpp \ ui/dialog/inkscape-preferences.h \ - ui/dialog/input.cpp \ - ui/dialog/input.h \ - ui/dialog/livepatheffect-editor.cpp \ - ui/dialog/livepatheffect-editor.h \ + ui/dialog/input.cpp \ + ui/dialog/input.h \ + ui/dialog/livepatheffect-editor.cpp \ + ui/dialog/livepatheffect-editor.h \ ui/dialog/memory.cpp \ ui/dialog/memory.h \ ui/dialog/messages.cpp \ ui/dialog/messages.h \ + ui/dialog/ocaldialogs.cpp \ + ui/dialog/ocaldialogs.h \ + ui/dialog/panel-dialog.h \ ui/dialog/print.cpp \ ui/dialog/print.h \ ui/dialog/scriptdialog.cpp \ ui/dialog/scriptdialog.h \ - ui/dialog/svg-fonts-dialog.cpp \ + ui/dialog/svg-fonts-dialog.cpp \ ui/dialog/svg-fonts-dialog.h \ + ui/dialog/tile.cpp \ + ui/dialog/tile.h \ ui/dialog/tracedialog.cpp \ ui/dialog/tracedialog.h \ ui/dialog/transformation.cpp \ ui/dialog/transformation.h \ ui/dialog/undo-history.cpp \ ui/dialog/undo-history.h \ - $(inkboard_dialogs) \ - ui/dialog/aboutbox.cpp \ - ui/dialog/aboutbox.h \ - ui/dialog/ocaldialogs.cpp \ - ui/dialog/ocaldialogs.h \ - ui/dialog/filedialogimpl-win32.h \ - ui/dialog/filedialogimpl-win32.cpp + $(inkboard_dialogs) ui/dialog/aboutbox.$(OBJEXT): inkscape_version.h diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 367a744c7..b509d041f 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -161,7 +161,7 @@ private : selected.erase(master); /*}*/ //Compute the anchor point - boost::optional<Geom::Rect> b = sp_item_bbox_desktop (thing); + Geom::OptRect b = sp_item_bbox_desktop (thing); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -178,7 +178,7 @@ private : case AlignAndDistribute::DRAWING: { - boost::optional<Geom::Rect> b = sp_item_bbox_desktop + Geom::OptRect b = sp_item_bbox_desktop ( (SPItem *) sp_document_root (sp_desktop_document (desktop)) ); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], @@ -191,7 +191,7 @@ private : case AlignAndDistribute::SELECTION: { - boost::optional<Geom::Rect> b = selection->bounds(); + Geom::OptRect b = selection->bounds(); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -216,7 +216,7 @@ private : prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); bool changed = false; - boost::optional<Geom::Rect> b; + Geom::OptRect b; if (sel_as_group) b = selection->bounds(); @@ -331,7 +331,7 @@ private : it != selected.end(); ++it) { - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); + Geom::OptRect bbox = sp_item_bbox_desktop(*it); if (bbox) { sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd)); } @@ -607,7 +607,7 @@ private : //Check 2 or more selected objects if (selected.size() < 2) return; - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); if (!sel_bbox) { return; } @@ -629,7 +629,7 @@ private : ++it) { sp_document_ensure_up_to_date(sp_desktop_document (desktop)); - boost::optional<Geom::Rect> item_box = sp_item_bbox_desktop (*it); + Geom::OptRect item_box = sp_item_bbox_desktop (*it); if (item_box) { // find new center, staying within bbox double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 + @@ -780,7 +780,7 @@ void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*cont void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) { - daad->randomize_bbox = boost::optional<Geom::Rect>(); + daad->randomize_bbox = Geom::OptRect(); } ///////////////////////////////////////////////////////// @@ -961,7 +961,7 @@ AlignAndDistribute::AlignAndDistribute() // Connect to the global selection change, to invalidate cached randomize_bbox g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); - randomize_bbox = boost::optional<Geom::Rect>(); + randomize_bbox = Geom::OptRect(); show_all_children(); @@ -1106,7 +1106,7 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem { gdouble max = -1e18; for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) { - boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it); + Geom::OptRect b = sp_item_bbox_desktop (*it); if (b) { gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim > max) { @@ -1123,7 +1123,7 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem { gdouble max = 1e18; for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) { - boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it); + Geom::OptRect b = sp_item_bbox_desktop (*it); if (b) { gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim < max) { diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index 3d6b5984e..0d41bb221 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -65,7 +65,7 @@ public: std::list<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal); void setMode(bool nodeEdit); - boost::optional<Geom::Rect> randomize_bbox; + Geom::OptRect randomize_bbox; protected: diff --git a/src/dialogs/debugdialog.cpp b/src/ui/dialog/debug.cpp index 42bf96050..b40796627 100644 --- a/src/dialogs/debugdialog.cpp +++ b/src/ui/dialog/debug.cpp @@ -1,14 +1,11 @@ -/* - * A very simple dialog for displaying Inkscape messages. Messages - * sent to g_log(), g_warning(), g_message(), ets, are routed here, - * in order to avoid messing with the startup console. - * - * Authors: +/** @file + * @brief A dialog that displays log messages + */ +/* Authors: * Bob Jamison * Other dudes from The Inkscape Organization * * Copyright (C) 2004 The Inkscape Organization - * * Released under GNU GPL, read the file 'COPYING' for more information */ #ifdef HAVE_CONFIG_H @@ -23,78 +20,32 @@ #include <gtkmm/menubar.h> #include <gtkmm/scrolledwindow.h> -#include "debugdialog.h" +#include "debug.h" namespace Inkscape { namespace UI { -namespace Dialogs { - - -//######################################################################### -//## I M P L E M E N T A T I O N -//######################################################################### +namespace Dialog { /** - * A dialog that displays log messages + * @brief A very simple dialog for displaying Inkscape messages - implementation */ class DebugDialogImpl : public DebugDialog, public Gtk::Dialog { - - public: - - - /** - * Constructor - */ +public: DebugDialogImpl(); - - /** - * Destructor - */ ~DebugDialogImpl(); - - /** - * Show the dialog - */ void show(); - - /** - * Do not show the dialog - */ void hide(); - - /** - * Clear all information from the dialog - */ void clear(); - - /** - * Display a message - */ void message(char const *msg); - - /** - * Redirect g_log() messages to this widget - */ void captureLogMessages(); - - /** - * Return g_log() messages to normal handling - */ void releaseLogMessages(); - - - private: - - +private: Gtk::MenuBar menuBar; - Gtk::Menu fileMenu; - Gtk::ScrolledWindow textScroll; - Gtk::TextView messageText; //Handler ID's @@ -104,32 +55,14 @@ class DebugDialogImpl : public DebugDialog, public Gtk::Dialog guint handlerPangomm; guint handlerGdkmm; guint handlerGtkmm; - }; - - - -//######################################################################### -//## E V E N T S -//######################################################################### - -/** - * Also a public method. Remove all text from the dialog - */ void DebugDialogImpl::clear() { Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer(); buffer->erase(buffer->begin(), buffer->end()); } - -//######################################################################### -//## C O N S T R U C T O R / D E S T R U C T O R -//######################################################################### -/** - * Constructor - */ DebugDialogImpl::DebugDialogImpl() { set_title(_("Messages")); @@ -168,30 +101,17 @@ DebugDialogImpl::DebugDialogImpl() handlerGtkmm = 0; } -/** - * Factory method. Use this to create a new DebugDialog - */ + DebugDialog *DebugDialog::create() { DebugDialog *dialog = new DebugDialogImpl(); return dialog; } - -/** - * Constructor - */ DebugDialogImpl::~DebugDialogImpl() { - - } - -//######################################################################### -//## M E T H O D S -//######################################################################### - void DebugDialogImpl::show() { //call super() @@ -201,16 +121,12 @@ void DebugDialogImpl::show() Gtk::Dialog::present(); } - - void DebugDialogImpl::hide() { - //call super() + // call super Gtk::Dialog::hide(); } - - void DebugDialogImpl::message(char const *msg) { Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer(); @@ -220,16 +136,14 @@ void DebugDialogImpl::message(char const *msg) buffer->insert (buffer->end(), uMsg); } - /* static instance, to reduce dependencies */ static DebugDialog *debugDialogInstance = NULL; DebugDialog *DebugDialog::getInstance() { - if ( !debugDialogInstance ) - { + if (!debugDialogInstance) { debugDialogInstance = new DebugDialogImpl(); - } + } return debugDialogInstance; } @@ -251,9 +165,7 @@ void dialogLoggingFunction(const gchar */*log_domain*/, gpointer user_data) { DebugDialogImpl *dlg = (DebugDialogImpl *)user_data; - dlg->message(messageText); - } @@ -263,74 +175,62 @@ void DebugDialogImpl::captureLogMessages() This might likely need more code, to capture Gtkmm and Glibmm warnings, or maybe just simply grab stdout/stderr */ - GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | + GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG); - if ( !handlerDefault ) - { + if ( !handlerDefault ) { handlerDefault = g_log_set_handler(NULL, flags, dialogLoggingFunction, (gpointer)this); - } - if ( !handlerGlibmm ) - { + } + if ( !handlerGlibmm ) { handlerGlibmm = g_log_set_handler("glibmm", flags, dialogLoggingFunction, (gpointer)this); - } - if ( !handlerAtkmm ) - { + } + if ( !handlerAtkmm ) { handlerAtkmm = g_log_set_handler("atkmm", flags, dialogLoggingFunction, (gpointer)this); - } - if ( !handlerPangomm ) - { + } + if ( !handlerPangomm ) { handlerPangomm = g_log_set_handler("pangomm", flags, dialogLoggingFunction, (gpointer)this); - } - if ( !handlerGdkmm ) - { + } + if ( !handlerGdkmm ) { handlerGdkmm = g_log_set_handler("gdkmm", flags, dialogLoggingFunction, (gpointer)this); - } - if ( !handlerGtkmm ) - { + } + if ( !handlerGtkmm ) { handlerGtkmm = g_log_set_handler("gtkmm", flags, dialogLoggingFunction, (gpointer)this); - } + } message("log capture started"); } void DebugDialogImpl::releaseLogMessages() { - if ( handlerDefault ) - { + if ( handlerDefault ) { g_log_remove_handler(NULL, handlerDefault); handlerDefault = 0; - } - if ( handlerGlibmm ) - { + } + if ( handlerGlibmm ) { g_log_remove_handler("glibmm", handlerGlibmm); handlerGlibmm = 0; - } - if ( handlerAtkmm ) - { + } + if ( handlerAtkmm ) { g_log_remove_handler("atkmm", handlerAtkmm); handlerAtkmm = 0; - } - if ( handlerPangomm ) - { + } + if ( handlerPangomm ) { g_log_remove_handler("pangomm", handlerPangomm); handlerPangomm = 0; - } - if ( handlerGdkmm ) - { + } + if ( handlerGdkmm ) { g_log_remove_handler("gdkmm", handlerGdkmm); handlerGdkmm = 0; - } - if ( handlerGtkmm ) - { + } + if ( handlerGtkmm ) { g_log_remove_handler("gtkmm", handlerGtkmm); handlerGtkmm = 0; - } + } message("log capture discontinued"); } @@ -340,9 +240,13 @@ void DebugDialogImpl::releaseLogMessages() } //namespace UI } //namespace Inkscape -//######################################################################### -//## E N D O F F I L E -//######################################################################### - - - +/* + 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/dialogs/debugdialog.h b/src/ui/dialog/debug.h index 1a4a036fd..f2ad61dd4 100644 --- a/src/dialogs/debugdialog.h +++ b/src/ui/dialog/debug.h @@ -1,11 +1,7 @@ -#ifndef __DEBUGDIALOG_H__ -#define __DEBUGDIALOG_H__ -/* - * A very simple dialog for displaying Inkscape messages. Messages - * sent to g_log(), g_warning(), g_message(), ets, are routed here, - * in order to avoid messing with the startup console. - * - * Authors: +/** @file + * @brief Dialog for displaying Inkscape messages + */ +/* Authors: * Bob Jamison * Other dudes from The Inkscape Organization * @@ -14,28 +10,24 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - +#ifndef SEEN_UI_DIALOGS_DEBUGDIALOG_H +#define SEEN_UI_DIALOGS_DEBUGDIALOG_H namespace Inkscape { namespace UI { -namespace Dialogs { +namespace Dialog { /** - * A dialog that displays log messages + * @brief A very simple dialog for displaying Inkscape messages. + * + * Messages sent to g_log(), g_warning(), g_message(), ets, are routed here, + * in order to avoid messing with the startup console. */ class DebugDialog { - - public: - - - /** - * Constructor - */ +public: DebugDialog() {}; - - /** * Factory method */ @@ -58,7 +50,9 @@ class DebugDialog virtual void hide() = 0; /** - * Clear all information from the dialog + * @brief Clear all information from the dialog + * + * Also a public method. Remove all text from the dialog */ virtual void clear() = 0; @@ -78,27 +72,29 @@ class DebugDialog virtual void releaseLogMessages() = 0; /** - * Get a shared singleton instance - */ + * Factory method. Use this to create a new DebugDialog + */ static DebugDialog *getInstance(); /** * Show the instance above */ static void showInstance(); - - - - }; - } //namespace Dialogs } //namespace UI } //namespace Inkscape - - - #endif /* __DEBUGDIALOG_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:encoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index e73200a1f..7a8947adf 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -1,13 +1,13 @@ -/** - * \brief Object for managing a set of dialogs, including their signals and +/** @file + * @brief Object for managing a set of dialogs, including their signals and * construction/caching/destruction of them. - * - * Authors: + */ +/* Authors: * Bryce W. Harrington <bryce@bryceharrington.org> * Jon Phillips <jon@rejon.org> * Gustav Broberg <broberg@kth.se> * - * Copyright (C) 2004--2007 Authors + * Copyright (C) 2004-2007 Authors * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -34,13 +34,13 @@ #ifdef ENABLE_SVG_FONTS #include "ui/dialog/svg-fonts-dialog.h" #endif // ENABLE_SVG_FONTS +#include "ui/dialog/tile.h" #include "ui/dialog/tracedialog.h" #include "ui/dialog/transformation.h" #include "ui/dialog/undo-history.h" #include "ui/dialog/panel-dialog.h" #include "dialogs/layers-panel.h" -#include "dialogs/tiledialog.h" #include "dialogs/iconpreview.h" #include "ui/dialog/floating-behavior.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 7c738c503..acf4dbb54 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -26,20 +26,30 @@ #include "ui/widget/scalar-unit.h" #include "xml/node-event-vector.h" +#include "xml/repr.h" #include "helper/units.h" #include "preferences.h" #include "inkscape.h" +#include "io/sys.h" #include "verbs.h" #include "document.h" #include "desktop-handles.h" #include "desktop.h" #include "sp-namedview.h" +#include "sp-object-repr.h" +#include "sp-root.h" #include "widgets/icon.h" #include "document-properties.h" #include "display/canvas-grid.h" +#if ENABLE_LCMS +#include <lcms.h> +//#include "color-profile-fns.h" +#include "color-profile.h" +#endif // ENABLE_LCMS + using std::pair; namespace Inkscape { @@ -82,7 +92,7 @@ DocumentProperties::getInstance() DocumentProperties::DocumentProperties() : UI::Widget::Panel ("", "/dialogs/documentoptions", SP_VERB_DIALOG_NAMEDVIEW), _page_page(1, 1, true, true), _page_guides(1, 1), - _page_snap(1, 1), _page_snap_dtls(1, 1), + _page_snap(1, 1), _page_snap_dtls(1, 1), _page_cms(1, 1), //--------------------------------------------------------------- _rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false), _rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false), @@ -100,7 +110,6 @@ DocumentProperties::DocumentProperties() _rcp_hgui(_("_Highlight color:"), _("Highlighted guideline color"), _("Color of a guideline when it is under mouse"), "guidehicolor", "guidehiopacity", _wr), //--------------------------------------------------------------- _rcbs(_("_Enable snapping"), _("Toggle snapping on or off"), "inkscape:snap-global", _wr), - _rcbsi(_("_Enable snap indicator"), _("After snapping, a symbol is drawn at the point that has snapped"), "inkscape:snap-indicator", _wr), _rcbsnbb(_("_Bounding box corners"), _("Only available in the selector tool: snap bounding box corners to guides, to grids, and to other bounding boxes (but not to nodes or paths)"), "inkscape:snap-bbox", _wr), _rcbsnn(_("_Nodes"), _("Snap nodes (e.g. path nodes, special points in shapes, gradient handles, text base points, transformation origins, etc.) to guides, to grids, to paths and to other nodes"), @@ -135,12 +144,16 @@ DocumentProperties::DocumentProperties() _notebook.append_page(_grids_vbox, _("Grids")); _notebook.append_page(_page_snap, _("Snap")); _notebook.append_page(_page_snap_dtls, _("Snap points")); + _notebook.append_page(_page_cms, _("Color Management")); build_page(); build_guides(); build_gridspage(); build_snap(); build_snap_dtls(); +#if ENABLE_LCMS + build_cms(); +#endif // ENABLE_LCMS _grids_button_new.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onNewGrid)); _grids_button_remove.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onRemoveGrid)); @@ -312,8 +325,6 @@ DocumentProperties::build_snap() slaves.clear(); slaves.push_back(&_rcbsnn); slaves.push_back(&_rcbsnbb); - slaves.push_back(&_rcbsi); - _rcbs.setSlaveWidgets(slaves); Gtk::Label *label_g = manage (new Gtk::Label); @@ -331,7 +342,6 @@ DocumentProperties::build_snap() { label_g, 0, 0, &_rcbs, - 0, &_rcbsi, 0, 0, label_w, 0, 0, &_rcbsnn, @@ -375,12 +385,208 @@ DocumentProperties::build_snap_dtls() 0, 0, label_m, 0, 0, &_rcbic, - 0, &_rcbsm + 0, &_rcbsm }; attach_all(_page_snap_dtls.table(), array, G_N_ELEMENTS(array)); } +#if ENABLE_LCMS +static void +lcms_profile_get_name (cmsHPROFILE profile, const gchar **name) +{ + if (profile) + { + *name = cmsTakeProductDesc (profile); + + if (! *name) + *name = cmsTakeProductName (profile); + + if (*name && ! g_utf8_validate (*name, -1, NULL)) + *name = _("(invalid UTF-8 string)"); + } + else + { + *name = _("None"); + } +} + +void +DocumentProperties::populate_available_profiles(){ + + // add "None" +/* Gtk::MenuItem *i = new Gtk::MenuItem(); + i->show(); + + i->set_data("filepath", NULL); + i->set_data("name", _("None")); + + Gtk::HBox *hb = new Gtk::HBox(false, 0); + hb->show(); + + Gtk::Label *l = new Gtk::Label( _("None") ); + l->show(); + l->set_alignment(0.0, 0.5); + + hb->pack_start(*l, true, true, 0); + + hb->show(); + i->add(*hb); + _menu.append(*i); +*/ + std::list<gchar *> sources; + sources.push_back( profile_path("color/icc") ); + //sources.push_back( g_strdup(INKSCAPE_COLORPROFILESDIR) ); + + int index = 1; + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + + if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) + && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { + GError *err = 0; + GDir *directory = g_dir_open(dirname, 0, &err); + if (!directory) { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + g_warning(_("Color profiles directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } else { + gchar *filename = 0; + while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { + gchar* lower = g_ascii_strdown( filename, -1 ); + gchar* full = g_build_filename(dirname, filename, NULL); + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + cmsHPROFILE hProfile = cmsOpenProfileFromFile(full, "r"); + if (hProfile != NULL){ + const gchar* name; + lcms_profile_get_name(hProfile, &name); + Gtk::MenuItem* mi = new Gtk::MenuItem(); + mi->set_data("filepath", g_strdup(full)); + mi->set_data("name", g_strdup(name)); + Gtk::HBox *hbox = new Gtk::HBox(); + hbox->show(); + Gtk::Label* lbl = manage(new Gtk::Label(name)); + lbl->show(); + hbox->pack_start(*lbl, true, true, 0); + mi->add(*hbox); + mi->show_all(); + _menu.append(*mi); + // g_free((void*)name); + } + cmsCloseProfile(hProfile); + index++; + } + g_free(full); + g_free(lower); + } + g_dir_close(directory); + } + } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + } + _menu.show_all(); +} + +void +DocumentProperties::onEmbedProfile() +{ +//store this profile in the SVG document (create <color-profile> element in the XML) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!desktop){ + g_warning("No active desktop"); + return; + } + Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc()); + Inkscape::XML::Node *cprofRepr = xml_doc->createElement("svg:color-profile"); + cprofRepr->setAttribute("name", (gchar*) _menu.get_active()->get_data("name")); + cprofRepr->setAttribute("xlink:href", (gchar*) _menu.get_active()->get_data("filepath")); + + /* Checks whether there is a defs element. Creates it when needed */ + Inkscape::XML::Node *defsRepr = sp_repr_lookup_name(xml_doc, "svg:defs"); + if (!defsRepr){ + defsRepr = xml_doc->createElement("svg:defs"); + xml_doc->root()->addChild(defsRepr, NULL); + } + + g_assert(SP_ROOT(desktop->doc()->root)->defs); + defsRepr->addChild(cprofRepr, NULL); + + Inkscape::GC::release(defsRepr); + + // inform the document, so we can undo + sp_document_done(desktop->doc(), SP_VERB_EMBED_COLOR_PROFILE, _("Embed Color Profile")); + + populate_embedded_profiles_box(); +} + +void +DocumentProperties::populate_embedded_profiles_box() +{ + _EmbeddedProfilesListStore->clear(); + const GSList *current = sp_document_get_resource_list( SP_ACTIVE_DOCUMENT, "iccprofile" ); + while ( current ) { + SPObject* obj = SP_OBJECT(current->data); + Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj); + Gtk::TreeModel::Row row = *(_EmbeddedProfilesListStore->append()); + row[_EmbeddedProfilesListColumns.nameColumn] = prof->name; +// row[_EmbeddedProfilesListColumns.previewColumn] = "Color Preview"; + current = g_slist_next(current); + } +} + + +void +DocumentProperties::build_cms() +{ + _page_cms.show(); + + Gtk::Label *label_embed= manage (new Gtk::Label); + label_embed->set_markup (_("<b>Embedded Color Profiles:</b>")); + Gtk::Label *label_avail = manage (new Gtk::Label); + label_avail->set_markup (_("<b>Available Color Profiles:</b>")); + + _embed_btn.set_label("Embed Profile"); + + Gtk::Widget *const array[] = + { + label_embed, 0, + &_EmbeddedProfilesListScroller, 0, + label_avail, 0, + &_combo_avail, &_embed_btn, + }; + + attach_all(_page_cms.table(), array, G_N_ELEMENTS(array)); + + populate_available_profiles(); + + _combo_avail.set_menu(_menu); + _combo_avail.set_history(0); + _combo_avail.show_all(); + + //# Set up the Embedded Profiles combo box + _EmbeddedProfilesListStore = Gtk::ListStore::create(_EmbeddedProfilesListColumns); + _EmbeddedProfilesList.set_model(_EmbeddedProfilesListStore); + _EmbeddedProfilesList.append_column(_("Profile Name"), _EmbeddedProfilesListColumns.nameColumn); +// _EmbeddedProfilesList.append_column(_("Color Preview"), _EmbeddedProfilesListColumns.previewColumn); + _EmbeddedProfilesList.set_headers_visible(false); + _EmbeddedProfilesList.set_fixed_height_mode(true); + + populate_embedded_profiles_box(); + + _EmbeddedProfilesListScroller.add(_EmbeddedProfilesList); + _EmbeddedProfilesListScroller.set_shadow_type(Gtk::SHADOW_IN); + _EmbeddedProfilesListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS); + _EmbeddedProfilesListScroller.set_size_request(-1, 90); + + _embed_btn.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onEmbedProfile)); +} +#endif // ENABLE_LCMS + /** * Called for _updating_ the dialog (e.g. when a new grid was manually added in XML) */ @@ -515,8 +721,6 @@ DocumentProperties::update() _rsu_gusn.setValue (nv->guidetolerance); _rcbs.setActive (nv->snap_manager.snapprefs.getSnapEnabledGlobally()); - _rcbsi.setActive (nv->snapindicator); - //-----------------------------------------------------------grids page update_gridspage(); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index ab70b0d07..ff4739bfb 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -50,8 +50,15 @@ protected: void build_snap(); void build_snap_dtls(); void build_gridspage(); +#if ENABLE_LCMS + void build_cms(); +#endif // ENABLE_LCMS void init(); + + void populate_available_profiles(); + void populate_embedded_profiles_box(); virtual void on_response (int); + void onEmbedProfile(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); @@ -61,7 +68,7 @@ protected: Gtk::Notebook _notebook; NotebookPage _page_page, _page_guides; - NotebookPage _page_snap, _page_snap_dtls; + NotebookPage _page_snap, _page_snap_dtls, _page_cms; Gtk::VBox _grids_vbox; Registry _wr; @@ -74,13 +81,29 @@ protected: RegisteredCheckButton _rcb_sgui, _rcbsng; RegisteredColorPicker _rcp_gui, _rcp_hgui; //--------------------------------------------------------------- - RegisteredCheckButton _rcbs, _rcbsi, _rcbsnbb, _rcbsnn, _rcbsnop; + RegisteredCheckButton _rcbs, _rcbsnbb, _rcbsnn, _rcbsnop; RegisteredCheckButton _rcbsnon, _rcbsnbbp, _rcbsnbbn, _rcbsnpb; ToleranceSlider _rsu_sno, _rsu_sn, _rsu_gusn; //--------------------------------------------------------------- RegisteredCheckButton _rcbic, _rcbsm; RegisteredCheckButton _rcbsigg, _rcbsils; //--------------------------------------------------------------- + Gtk::Menu _menu; + Gtk::OptionMenu _combo_avail; + Gtk::Button _embed_btn; + class EmbeddedProfilesColumns : public Gtk::TreeModel::ColumnRecord + { + public: + EmbeddedProfilesColumns() + { add(nameColumn); add(previewColumn); } + Gtk::TreeModelColumn<Glib::ustring> nameColumn; + Gtk::TreeModelColumn<Glib::ustring> previewColumn; + }; + EmbeddedProfilesColumns _EmbeddedProfilesListColumns; + Glib::RefPtr<Gtk::ListStore> _EmbeddedProfilesListStore; + Gtk::TreeView _EmbeddedProfilesList; + Gtk::ScrolledWindow _EmbeddedProfilesListScroller; + //--------------------------------------------------------------- Gtk::Notebook _grids_notebook; Gtk::HBox _grids_hbox_crea; Gtk::Label _grids_label_crea; diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index b47f2ccc7..d91af244b 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -864,7 +864,7 @@ bool FileOpenDialogImplWin32::set_svg_preview() NRRectL bbox = {0, 0, scaledSvgWidth, scaledSvgHeight}; // write object bbox to area - boost::optional<Geom::Rect> maybeArea(area); + Geom::OptRect maybeArea(area); sp_document_ensure_up_to_date (svgDoc); sp_item_invoke_bbox((SPItem *) svgDoc->root, maybeArea, sp_item_i2r_affine((SPItem *)(svgDoc->root)), TRUE); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 799bb2a24..08df7fd05 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -41,18 +41,18 @@ #include "path-prefix.h" #include "preferences.h" #include "selection.h" -#include "sp-feblend.h" -#include "sp-fecolormatrix.h" -#include "sp-fecomponenttransfer.h" -#include "sp-fecomposite.h" -#include "sp-feconvolvematrix.h" -#include "sp-fedisplacementmap.h" -#include "sp-fedistantlight.h" -#include "sp-femerge.h" -#include "sp-femergenode.h" -#include "sp-feoffset.h" -#include "sp-fepointlight.h" -#include "sp-fespotlight.h" +#include "filters/blend.h" +#include "filters/colormatrix.h" +#include "filters/componenttransfer.h" +#include "filters/composite.h" +#include "filters/convolvematrix.h" +#include "filters/displacementmap.h" +#include "filters/distantlight.h" +#include "filters/merge.h" +#include "filters/mergenode.h" +#include "filters/offset.h" +#include "filters/pointlight.h" +#include "filters/spotlight.h" #include "sp-filter-primitive.h" #include "sp-gaussian-blur.h" @@ -84,7 +84,7 @@ int input_count(const SPFilterPrimitive* prim) else if(SP_IS_FEMERGE(prim)) { // Return the number of feMergeNode connections plus an extra int count = 1; - for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count); + for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count){}; return count; } else @@ -1821,7 +1821,7 @@ int FilterEffectsDialog::PrimitiveList::find_index(const Gtk::TreeIter& target) { int i = 0; for(Gtk::TreeIter iter = _model->children().begin(); - iter != target; ++iter, ++i); + iter != target; ++iter, ++i){}; return i; } diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index d06d3a406..a436ce867 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -114,6 +114,7 @@ InkscapePreferences::InkscapePreferences() initPageUI(); initPageMouse(); initPageScrolling(); + initPageSnapping(); initPageSteps(); initPageWindows(); initPageMisc(); @@ -198,6 +199,20 @@ void InkscapePreferences::initPageScrolling() _("When on, mouse wheel zooms without Ctrl and scrolls canvas with Ctrl; when off, it zooms with Ctrl and scrolls without Ctrl.")); } +void InkscapePreferences::initPageSnapping() +{ + + _snap_indicator.init( _("Enable snap indicator"), "/options/snapindicator/value", true); + _page_snapping.add_line( false, "", _snap_indicator, "", + _("After snapping, a symbol is drawn at the point that has snapped")); + + _snap_delay.init("/options/snapdelay/value", 0, 1000, 50, 100, 300, 0); + _page_snapping.add_line( false, _("Delay (in msec):"), _snap_delay, "", + _("Postpone snapping as long as the mouse is moving, and then wait an additional fraction of a second. This additional delay is specified here. When set to zero or to a very small number, snapping will be immediate"), true); + + this->AddPage(_page_snapping, _("Snapping"), PREFS_PAGE_SNAPPING); +} + void InkscapePreferences::initPageSteps() { this->AddPage(_page_steps, _("Steps"), PREFS_PAGE_STEPS); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 98ecda855..a957ce657 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -72,6 +72,7 @@ enum { PREFS_PAGE_UI, PREFS_PAGE_MOUSE, PREFS_PAGE_SCROLLING, + PREFS_PAGE_SNAPPING, PREFS_PAGE_STEPS, PREFS_PAGE_WINDOWS, PREFS_PAGE_MISC @@ -110,7 +111,7 @@ protected: Gtk::TreeModel::Path _path_tools; Gtk::TreeModel::Path _path_shapes; - DialogPage _page_mouse, _page_scrolling, _page_steps, _page_tools, _page_windows, + DialogPage _page_mouse, _page_scrolling, _page_snapping, _page_steps, _page_tools, _page_windows, _page_clones, _page_mask, _page_transforms, _page_filters, _page_select, _page_importexport, _page_cms, _page_grids, _page_svgoutput, _page_misc, _page_ui, _page_autosave, _page_bitmaps; @@ -125,6 +126,9 @@ protected: PrefSpinButton _scroll_wheel, _scroll_arrow_px, _scroll_arrow_acc, _scroll_auto_speed, _scroll_auto_thres; PrefCheckButton _scroll_space; PrefCheckButton _wheel_zoom; + + Gtk::HScale *_slider_snapping_delay; + PrefCheckButton _snap_indicator; PrefCombo _steps_rot_snap; PrefCheckButton _steps_compass; @@ -172,6 +176,7 @@ protected: PrefSpinButton _importexport_export, _misc_recent, _misc_simpl; ZoomCorrRulerSlider _ui_zoom_correction; + PrefSlider _snap_delay; PrefSpinButton _misc_latency_skew; PrefCheckButton _misc_comment, _misc_forkvectors, _misc_scripts, _misc_namedicon_delay; PrefCombo _misc_small_toolbar; @@ -255,6 +260,7 @@ protected: void on_pagelist_selection_changed(); void initPageMouse(); void initPageScrolling(); + void initPageSnapping(); void initPageSteps(); void initPageTools(); void initPageWindows(); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 8a7e0adeb..1c66160dd 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -27,6 +27,7 @@ #include "path-chemistry.h" #include "live_effects/effect.h" #include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" #include "gtkmm/widget.h" #include <vector> #include "inkscape.h" diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h index 370bd599a..1152e8bb8 100644 --- a/src/ui/dialog/livepatheffect-editor.h +++ b/src/ui/dialog/livepatheffect-editor.h @@ -19,8 +19,7 @@ #include <gtkmm/frame.h> #include <gtkmm/tooltips.h> #include "ui/widget/combo-enums.h" -#include "live_effects/effect.h" -#include "live_effects/lpeobject-reference.h" +#include "live_effects/effect-enum.h" #include <gtkmm/liststore.h> #include <gtkmm/treeview.h> #include <gtkmm/scrolledwindow.h> @@ -29,9 +28,15 @@ class SPDesktop; +class SPLPEItem; namespace Inkscape { +namespace LivePathEffect { + class Effect; + class LPEObjectReference; +} + namespace UI { namespace Dialog { diff --git a/src/ui/dialog/messages.cpp b/src/ui/dialog/messages.cpp index 958256310..31f9cc51e 100644 --- a/src/ui/dialog/messages.cpp +++ b/src/ui/dialog/messages.cpp @@ -99,8 +99,8 @@ void Messages::message(char *msg) buffer->insert (buffer->end(), uMsg); } - -void dialogLoggingFunction(const gchar */*log_domain*/, +// dialogLoggingCallback is already used in debug.cpp +static void dialogLoggingCallback(const gchar */*log_domain*/, GLogLevelFlags /*log_level*/, const gchar *messageText, gpointer user_data) @@ -123,27 +123,27 @@ void Messages::captureLogMessages() G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG); if ( !handlerDefault ) { handlerDefault = g_log_set_handler(NULL, flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } if ( !handlerGlibmm ) { handlerGlibmm = g_log_set_handler("glibmm", flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } if ( !handlerAtkmm ) { handlerAtkmm = g_log_set_handler("atkmm", flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } if ( !handlerPangomm ) { handlerPangomm = g_log_set_handler("pangomm", flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } if ( !handlerGdkmm ) { handlerGdkmm = g_log_set_handler("gdkmm", flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } if ( !handlerGtkmm ) { handlerGtkmm = g_log_set_handler("gtkmm", flags, - dialogLoggingFunction, (gpointer)this); + dialogLoggingCallback, (gpointer)this); } message((char*)"log capture started"); } diff --git a/src/dialogs/tiledialog.cpp b/src/ui/dialog/tile.cpp index f597c601b..7f45901c3 100644 --- a/src/dialogs/tiledialog.cpp +++ b/src/ui/dialog/tile.cpp @@ -17,7 +17,6 @@ # include <config.h> #endif - #include <gtk/gtkdialog.h> //for GTK_RESPONSE* types #include <gtk/gtksizegroup.h> #include <glibmm/i18n.h> @@ -31,9 +30,7 @@ #include "document.h" #include "sp-item.h" #include "widgets/icon.h" -#include "tiledialog.h" - - +#include "tile.h" /* * Sort items by their x co-ordinates, taking account of y (keeps rows intact) @@ -48,8 +45,8 @@ sp_compare_x_position(SPItem *first, SPItem *second) using Geom::X; using Geom::Y; - boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first)); - boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second)); + Geom::OptRect a = first->getBounds(sp_item_i2doc_affine(first)); + Geom::OptRect b = second->getBounds(sp_item_i2doc_affine(second)); if ( !a || !b ) { // FIXME? @@ -88,8 +85,8 @@ sp_compare_x_position(SPItem *first, SPItem *second) int sp_compare_y_position(SPItem *first, SPItem *second) { - boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first)); - boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second)); + Geom::OptRect a = first->getBounds(sp_item_i2doc_affine(first)); + Geom::OptRect b = second->getBounds(sp_item_i2doc_affine(second)); if ( !a || !b ) { // FIXME? @@ -168,7 +165,7 @@ void TileDialog::Grid_Arrange () cnt=0; for (; items != NULL; items = items->next) { SPItem *item = SP_ITEM(items->data); - boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item)); if (!b) { continue; } @@ -210,7 +207,7 @@ void TileDialog::Grid_Arrange () const GSList *sizes = sorted; for (; sizes != NULL; sizes = sizes->next) { SPItem *item = SP_ITEM(sizes->data); - boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item)); if (b) { width = b->dimensions()[Geom::X]; height = b->dimensions()[Geom::Y]; @@ -267,7 +264,7 @@ void TileDialog::Grid_Arrange () } - boost::optional<Geom::Rect> sel_bbox = selection->bounds(); + Geom::OptRect sel_bbox = selection->bounds(); // Fit to bbox, calculate padding between rows accordingly. if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ #ifdef DEBUG_GRID_ARRANGE @@ -317,7 +314,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h for (; current_row != NULL; current_row = current_row->next) { SPItem *item=SP_ITEM(current_row->data); Inkscape::XML::Node *repr = SP_OBJECT_REPR(item); - boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); + Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item)); Geom::Point min; if (b) { width = b->dimensions()[Geom::X]; diff --git a/src/dialogs/tiledialog.h b/src/ui/dialog/tile.h index a1201956a..075b2b33f 100644 --- a/src/dialogs/tiledialog.h +++ b/src/ui/dialog/tile.h @@ -1,9 +1,7 @@ -#ifndef __TILEDIALOG_H__ -#define __TILEDIALOG_H__ -/* - * A simple dialog for creating grid type arrangements of selected objects - * - * Authors: +/** @file + * @brief Dialog for creating grid type arrangements of selected objects + */ +/* Authors: * Bob Jamison ( based off trace dialog) * John Cliff * Other dudes from The Inkscape Organization @@ -14,6 +12,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_UI_DIALOG_TILE_H +#define SEEN_UI_DIALOG_TILE_H #include <gtkmm/box.h> #include <gtkmm/notebook.h> @@ -31,25 +31,11 @@ namespace Dialog { /** - * A dialog that displays log messages + * Dialog for tiling an object */ class TileDialog : public UI::Widget::Panel { - public: - - /** - * Constructor - */ TileDialog() ; - - /** - * Factory method - */ - static TileDialog& getInstance() { return *new TileDialog(); } - - /** - * Destructor - */ virtual ~TileDialog() {}; /** @@ -62,15 +48,12 @@ public: */ void updateSelection(); - /** * Callback from Apply */ virtual void _apply(); - /** - * Callback from spinbuttons - */ + // Callbacks from spinbuttons void on_row_spinbutton_changed(); void on_col_spinbutton_changed(); void on_xpad_spinbutton_changed(); @@ -83,6 +66,10 @@ public: void VertAlign_changed(); void HorizAlign_changed(); + static TileDialog& getInstance() { + static TileDialog instance; + return instance; + } private: TileDialog(TileDialog const &d); // no copy @@ -91,8 +78,6 @@ private: bool userHidden; bool updating; - - Gtk::Notebook notebook; Gtk::Tooltips tips; @@ -176,7 +161,6 @@ private: Gtk::HBox ColumnWidthBox; Gtk::Label ColumnWidthLabel; Gtk::SpinButton ColumnWidthSpinner; - }; @@ -187,3 +171,13 @@ private: #endif /* __TILEDIALOG_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:encoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 899053cc9..a242aaa4c 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -457,7 +457,7 @@ Transformation::updatePageMove(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (!_check_move_relative.get_active()) { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { double x = bbox->min()[Geom::X]; double y = bbox->min()[Geom::Y]; @@ -478,7 +478,7 @@ void Transformation::updatePageScale(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { double w = bbox->dimensions()[Geom::X]; double h = bbox->dimensions()[Geom::Y]; @@ -508,7 +508,7 @@ void Transformation::updatePageSkew(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { double w = bbox->dimensions()[Geom::X]; double h = bbox->dimensions()[Geom::Y]; @@ -605,7 +605,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) if (_check_move_relative.get_active()) { sp_selection_move_relative(selection, x, y); } else { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { sp_selection_move_relative(selection, x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); @@ -626,7 +626,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) it != selected.end(); ++it) { - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); + Geom::OptRect bbox = sp_item_bbox_desktop(*it); if (bbox) { sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.)); } @@ -650,7 +650,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) it != selected.end(); ++it) { - boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); + Geom::OptRect bbox = sp_item_bbox_desktop(*it); if (bbox) { sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.)); } @@ -669,7 +669,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) } } } else { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { sp_selection_move_relative(selection, x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); @@ -694,7 +694,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection) Geom::Scale scale (0,0); // the values are increments! if (_units_scale.isAbsolute()) { - boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item)); + Geom::OptRect bbox(sp_item_bbox_desktop(item)); if (bbox) { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object @@ -712,7 +712,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection) sp_item_scale_rel (item, scale); } } else { - boost::optional<Geom::Rect> bbox(selection->bounds()); + Geom::OptRect bbox(selection->bounds()); if (bbox) { Geom::Point center(bbox->midpoint()); // use rotation center? Geom::Scale scale (0,0); @@ -781,7 +781,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection) } else { // absolute displacement double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); - boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item)); + Geom::OptRect bbox(sp_item_bbox_desktop(item)); if (bbox) { double width = bbox->dimensions()[Geom::X]; double height = bbox->dimensions()[Geom::Y]; @@ -790,7 +790,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection) } } } else { // transform whole selection - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); boost::optional<Geom::Point> center = selection->center(); if ( bbox && center ) { @@ -873,7 +873,7 @@ Transformation::onMoveRelativeToggled() //g_message("onMoveRelativeToggled: %f, %f px\n", x, y); - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { if (_check_move_relative.get_active()) { @@ -1013,7 +1013,7 @@ Transformation::onClear() _scalar_move_horizontal.setValue(0); _scalar_move_vertical.setValue(0); } else { - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { _scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px"); _scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px"); diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp index 5e7713044..dd437aad8 100644 --- a/src/ui/view/edit-widget.cpp +++ b/src/ui/view/edit-widget.cpp @@ -1404,7 +1404,7 @@ EditWidget::updateScrollbars (double scale) Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)) ); SPObject* root = doc->root; SPItem* item = SP_ITEM(root); - boost::optional<Geom::Rect> deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); + Geom::OptRect deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); /* Canvas region we always show unconditionally */ Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64), diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 9e39af75f..3ef4c7328 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -125,7 +125,7 @@ ObjectCompositeSettings::_blendBlurValueChanged() // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); - boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); + Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); double radius; if (bbox) { double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? @@ -271,7 +271,7 @@ ObjectCompositeSettings::_subjectChanged() { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: - boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); + Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); if (bbox) { double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? _fe_cb.set_blur_sensitive(true); diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 72df1baab..395726511 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -461,6 +461,66 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET); } +void +PrefSlider::on_slider_value_changed() +{ + if (this->is_visible() || freeze) //only take action if user changed value + { + freeze = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(_prefs_path, _slider.get_value()); + _sb.set_value(_slider.get_value()); + freeze = false; + } +} + +void +PrefSlider::on_spinbutton_value_changed() +{ + if (this->is_visible() || freeze) //only take action if user changed value + { + freeze = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(_prefs_path, _sb.get_value()); + _slider.set_value(_sb.get_value()); + freeze = false; + } +} + +void +PrefSlider::init(Glib::ustring const &prefs_path, + double lower, double upper, double step_increment, double page_increment, double default_value, int digits) +{ + _prefs_path = prefs_path; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + double value = prefs->getDoubleLimited(prefs_path, default_value, lower, upper); + + freeze = false; + + _slider.set_range (lower, upper); + _slider.set_increments (step_increment, page_increment); + _slider.set_value (value); + _slider.set_digits(digits); + _slider.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed)); + + _sb.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_spinbutton_value_changed)); + _sb.set_range (lower, upper); + _sb.set_increments (step_increment, page_increment); + _sb.set_value (value); + _sb.set_digits(digits); + + Gtk::Table *table = Gtk::manage(new Gtk::Table()); + Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0)); + Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0)); + alignment1->add(_sb); + + table->attach(_slider, 0, 1, 0, 1); + table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0)); + + this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET); +} + void PrefCombo::init(Glib::ustring const &prefs_path, Glib::ustring labels[], int values[], int num_items, int default_value) { diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index dbc319c1a..1576184ac 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -122,6 +122,23 @@ private: bool freeze; // used to block recursive updates of slider and spinbutton }; +class PrefSlider : public Gtk::HBox +{ +public: + void init(Glib::ustring const &prefs_path, + double lower, double upper, double step_increment, double page_increment, double default_value, int digits); + +private: + void on_slider_value_changed(); + void on_spinbutton_value_changed(); + + Glib::ustring _prefs_path; + Gtk::SpinButton _sb; + Gtk::HScale _slider; + bool freeze; // used to block recursive updates of slider and spinbutton +}; + + class PrefCombo : public Gtk::ComboBoxText { public: diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp index a2e8a2547..a7359242d 100644 --- a/src/ui/widget/style-subject.cpp +++ b/src/ui/widget/style-subject.cpp @@ -65,12 +65,12 @@ StyleSubject::iterator StyleSubject::Selection::begin() { } } -boost::optional<Geom::Rect> StyleSubject::Selection::getBounds(SPItem::BBoxType type) { +Geom::OptRect StyleSubject::Selection::getBounds(SPItem::BBoxType type) { Inkscape::Selection *selection = _getSelection(); if (selection) { return selection->bounds(type); } else { - return boost::optional<Geom::Rect>(); + return Geom::OptRect(); } } @@ -143,12 +143,12 @@ StyleSubject::iterator StyleSubject::CurrentLayer::begin() { return iterator(_getLayerSList()); } -boost::optional<Geom::Rect> StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) { +Geom::OptRect StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) { SPObject *layer = _getLayer(); if (layer && SP_IS_ITEM(layer)) { return sp_item_bbox_desktop(SP_ITEM(layer), type); } else { - return boost::optional<Geom::Rect>(); + return Geom::OptRect(); } } diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h index 231a88728..6f46efff5 100644 --- a/src/ui/widget/style-subject.h +++ b/src/ui/widget/style-subject.h @@ -44,7 +44,7 @@ public: virtual iterator begin() = 0; virtual iterator end() { return iterator(NULL); } - virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0; + virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0; virtual int queryStyle(SPStyle *query, int property) = 0; virtual void setCSS(SPCSSAttr *css) = 0; @@ -67,7 +67,7 @@ public: ~Selection(); virtual iterator begin(); - virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); + virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); virtual int queryStyle(SPStyle *query, int property); virtual void setCSS(SPCSSAttr *css); @@ -88,7 +88,7 @@ public: ~CurrentLayer(); virtual iterator begin(); - virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); + virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); virtual int queryStyle(SPStyle *query, int property); virtual void setCSS(SPCSSAttr *css); diff --git a/src/verbs.cpp b/src/verbs.cpp index 37961ab15..4ddf58957 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1308,7 +1308,7 @@ ObjectVerb::perform( SPAction *action, void *data, void */*pdata*/ ) if (sel->isEmpty()) return; - boost::optional<Geom::Rect> bbox = sel->bounds(); + Geom::OptRect bbox = sel->bounds(); if (!bbox) { return; } diff --git a/src/verbs.h b/src/verbs.h index 8ae12f422..2bee018c5 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -19,6 +19,7 @@ #include <cstring> #include <string> #include <string.h> +#include "config.h" #include "require-config.h" /* HAVE_GTK_WINDOW_FULLSCREEN */ #include "helper/helper-forward.h" #include "forward.h" @@ -271,7 +272,9 @@ enum { SP_VERB_UNHIDE_ALL, SP_VERB_UNHIDE_ALL_IN_ALL_LAYERS, /* Footer */ - SP_VERB_LAST + SP_VERB_LAST, + /* Color management */ + SP_VERB_EMBED_COLOR_PROFILE, }; gchar *sp_action_get_title (const SPAction *action); diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index 33f589247..fdebe8d20 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -11,18 +11,18 @@ widgets/clean: rm -f widgets/libspwidgets.a $(widgets_libspwidgets_a_OBJECTS) widgets_libspwidgets_a_SOURCES = \ - widgets/button.cpp \ - widgets/button.h \ + widgets/button.cpp \ + widgets/button.h \ widgets/calligraphic-profile-rename.cpp \ widgets/calligraphic-profile-rename.h \ widgets/dash-selector.cpp \ - widgets/dash-selector.h \ + widgets/dash-selector.h \ widgets/dash-selector.cpp \ - widgets/dash-selector.h \ + widgets/dash-selector.h \ widgets/desktop-widget.cpp \ widgets/desktop-widget.h \ widgets/font-selector.cpp \ - widgets/font-selector.h \ + widgets/font-selector.h \ widgets/gradient-toolbar.cpp \ widgets/gradient-toolbar.h \ widgets/gradient-image.cpp \ @@ -31,14 +31,14 @@ widgets_libspwidgets_a_SOURCES = \ widgets/gradient-selector.h \ widgets/gradient-vector.cpp \ widgets/gradient-vector.h \ - widgets/icon.cpp \ - widgets/icon.h \ - widgets/layer-selector.h \ - widgets/layer-selector.cpp \ + widgets/icon.cpp \ + widgets/icon.h \ + widgets/layer-selector.h \ + widgets/layer-selector.cpp \ widgets/paint-selector.cpp \ widgets/paint-selector.h \ - widgets/ruler.cpp \ - widgets/ruler.h \ + widgets/ruler.cpp \ + widgets/ruler.h \ widgets/select-toolbar.cpp \ widgets/select-toolbar.h \ widgets/shrink-wrap-button.cpp \ @@ -61,8 +61,8 @@ widgets_libspwidgets_a_SOURCES = \ widgets/sp-color-wheel-selector.h \ widgets/sp-color-wheel.cpp \ widgets/sp-color-wheel.h \ - widgets/sp-widget.cpp \ - widgets/sp-widget.h\ + widgets/sp-widget.cpp \ + widgets/sp-widget.h \ widgets/sp-xmlview-attr-list.cpp \ widgets/sp-xmlview-attr-list.h \ widgets/sp-xmlview-content.cpp \ @@ -72,9 +72,9 @@ widgets_libspwidgets_a_SOURCES = \ widgets/spinbutton-events.cpp \ widgets/spinbutton-events.h \ widgets/spw-utilities.cpp \ - widgets/spw-utilities.h \ - widgets/toolbox.cpp \ - widgets/toolbox.h \ + widgets/spw-utilities.h \ + widgets/toolbox.cpp \ + widgets/toolbox.h \ widgets/widget-sizes.h widgets/button.$(OBJEXT): helper/sp-marshal.h diff --git a/src/widgets/calligraphic-profile-rename.cpp b/src/widgets/calligraphic-profile-rename.cpp index 45ad08aa9..888b327f4 100755..100644 --- a/src/widgets/calligraphic-profile-rename.cpp +++ b/src/widgets/calligraphic-profile-rename.cpp @@ -1,12 +1,14 @@ -/** +/** @file + * @brief Dialog for naming calligraphic profiles * - * \brief Dialog for naming calligraphic profiles - * - * Author: + * @note This file is in the wrong directory because of link order issues - + * it is required by widgets/toolbox.cpp, and libspwidgets.a comes after + * libinkdialogs.a in the current link order. + */ +/* Author: * Aubanel MONNIER * - * Copyright (C) 2007 Aubanel MONNIER - * + * Copyright (C) 2007 Authors * Released under GNU GPL. Read the file 'COPYING' for more information */ @@ -20,80 +22,87 @@ #include "desktop.h" #include "calligraphic-profile-rename.h" - namespace Inkscape { namespace UI { -namespace Dialogs { -CalligraphicProfileDialog::CalligraphicProfileDialog(): _applied(false){ - Gtk::VBox *mainVBox = get_vbox(); - _layout_table.set_spacings(4); - _layout_table.resize (1, 2); - - _profile_name_entry.set_activates_default(true); - - _profile_name_label.set_label(_("Profile name:")); - _profile_name_label.set_alignment(1.0, 0.5); - - _layout_table.attach(_profile_name_label, - 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); - _layout_table.attach(_profile_name_entry, - 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); - mainVBox->pack_start(_layout_table, false, false, 4); - // Buttons - _close_button.set_use_stock(true); - _close_button.set_label(Gtk::Stock::CANCEL.id); - _close_button.set_flags(Gtk::CAN_DEFAULT); - - _apply_button.set_use_underline(true); - _apply_button.set_label(_("Save")); - _apply_button.set_flags(Gtk::CAN_DEFAULT); - - _close_button.signal_clicked() - .connect(sigc::mem_fun(*this, &CalligraphicProfileDialog::_close)); - _apply_button.signal_clicked() - .connect(sigc::mem_fun(*this, &CalligraphicProfileDialog::_apply)); - - signal_delete_event().connect( - sigc::bind_return( - sigc::hide(sigc::mem_fun(*this, &CalligraphicProfileDialog::_close)), - true - ) - ); - - add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); - add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); - - _apply_button.grab_default(); - - show_all_children(); +namespace Dialog { + +CalligraphicProfileRename::CalligraphicProfileRename() : + _applied(false) +{ + Gtk::VBox *mainVBox = get_vbox(); + _layout_table.set_spacings(4); + _layout_table.resize (1, 2); + + _profile_name_entry.set_activates_default(true); + + _profile_name_label.set_label(_("Profile name:")); + _profile_name_label.set_alignment(1.0, 0.5); + _layout_table.attach(_profile_name_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_profile_name_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + mainVBox->pack_start(_layout_table, false, false, 4); + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_flags(Gtk::CAN_DEFAULT); + + _apply_button.set_use_underline(true); + _apply_button.set_label(_("Save")); + _apply_button.set_flags(Gtk::CAN_DEFAULT); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_apply)); + + signal_delete_event().connect( sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &CalligraphicProfileRename::_close)), true ) ); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); } -void -CalligraphicProfileDialog::_apply() +void CalligraphicProfileRename::_apply() { - _profile_name = _profile_name_entry.get_text(); - _applied = true; - _close(); + _profile_name = _profile_name_entry.get_text(); + _applied = true; + _close(); } -void -CalligraphicProfileDialog::_close() +void CalligraphicProfileRename::_close() { - this->Gtk::Dialog::hide(); - + this->Gtk::Dialog::hide(); } -void CalligraphicProfileDialog::show(SPDesktop *desktop){ - CalligraphicProfileDialog &dial = instance(); - dial._applied=false; - dial.set_modal(true); - desktop->setWindowTransient (dial.gobj()); - dial.property_destroy_with_parent() = true; - // dial.Gtk::Dialog::show(); - //dial.present(); - dial.run(); +void CalligraphicProfileRename::show(SPDesktop *desktop) +{ + CalligraphicProfileRename &dial = instance(); + dial._applied=false; + dial.set_modal(true); + desktop->setWindowTransient (dial.gobj()); + dial.property_destroy_with_parent() = true; + // dial.Gtk::Dialog::show(); + //dial.present(); + dial.run(); } - -}}} +} // namespace Dialog +} // namespace UI +} // 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/widgets/calligraphic-profile-rename.h b/src/widgets/calligraphic-profile-rename.h index f0e455c6c..53ce907ed 100755..100644 --- a/src/widgets/calligraphic-profile-rename.h +++ b/src/widgets/calligraphic-profile-rename.h @@ -1,12 +1,10 @@ -/** - * - * \brief Dialog for naming calligraphic profiles - * - * Author: +/** @file + * @brief Dialog for naming calligraphic profiles + */ +/* Author: * Aubanel MONNIER * - * Copyright (C) 2007 Aubanel MONNIER - * + * Copyright (C) 2007 Authors * Released under GNU GPL. Read the file 'COPYING' for more information */ @@ -20,38 +18,58 @@ struct SPDesktop; namespace Inkscape { - namespace UI { - namespace Dialogs { +namespace UI { +namespace Dialog { - class CalligraphicProfileDialog: public Gtk::Dialog { - public: - CalligraphicProfileDialog(); - virtual ~CalligraphicProfileDialog(){} ; - static void show(SPDesktop *desktop); - static bool applied(){return instance()._applied;} - static Glib::ustring getProfileName() { return instance()._profile_name;} - - Glib::ustring getName() const { return "CalligraphicProfileDialog"; } +class CalligraphicProfileRename : public Gtk::Dialog { +public: + CalligraphicProfileRename(); + virtual ~CalligraphicProfileRename() {} + Glib::ustring getName() const { + return "CalligraphicProfileRename"; + } + + static void show(SPDesktop *desktop); + static bool applied() { + return instance()._applied; + } + static Glib::ustring getProfileName() { + return instance()._profile_name; + } - - protected: - void _close(); - void _apply(); +protected: + void _close(); + void _apply(); - Gtk::Label _profile_name_label; - Gtk::Entry _profile_name_entry; - Gtk::Table _layout_table; - Gtk::Button _close_button; - Gtk::Button _apply_button; - Glib::ustring _profile_name; - bool _applied; - private: - static CalligraphicProfileDialog &instance(){static CalligraphicProfileDialog instance; return instance;} - CalligraphicProfileDialog(CalligraphicProfileDialog const &); // no copy - CalligraphicProfileDialog &operator=(CalligraphicProfileDialog const &); // no assign - }; + Gtk::Label _profile_name_label; + Gtk::Entry _profile_name_entry; + Gtk::Table _layout_table; + Gtk::Button _close_button; + Gtk::Button _apply_button; + Glib::ustring _profile_name; + bool _applied; +private: + static CalligraphicProfileRename &instance() { + static CalligraphicProfileRename instance_; + return instance_; } - } -} + CalligraphicProfileRename(CalligraphicProfileRename const &); // no copy + CalligraphicProfileRename &operator=(CalligraphicProfileRename const &); // no assign +}; + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape #endif // INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_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:encoding=utf-8:textwidth=99 : diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 3c78eb0bb..1fdf1fceb 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1700,7 +1700,7 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale) Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)) ); SPObject* root = doc->root; SPItem* item = SP_ITEM(root); - boost::optional<Geom::Rect> deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); + Geom::OptRect deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); /* Canvas region we always show unconditionally */ Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64), diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 49a35b5cb..502c34790 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -671,7 +671,7 @@ static gint sp_font_preview_expose(GtkWidget *widget, GdkEventExpose *event) hpos[len] = base_pt[0]; len++; if ( curF ) { - boost::optional<Geom::Rect> nbbox = curF->BBox(str_text->glyph_text[i].gl); + Geom::OptRect nbbox = curF->BBox(str_text->glyph_text[i].gl); if (nbbox) { bbox.x0 = MIN(bbox.x0, base_pt[Geom::X] + theSize * (nbbox->min())[0]); bbox.y0 = MIN(bbox.y0, base_pt[Geom::Y] - theSize * (nbbox->max())[1]); diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 4c0439da7..5aad614b4 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -662,7 +662,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, if (object && SP_IS_ITEM(object)) { /* Find bbox in document */ Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object))); - boost::optional<Geom::Rect> dbox = SP_ITEM(object)->getBounds(i2doc); + Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc); if ( SP_OBJECT_PARENT(object) == NULL ) { @@ -671,7 +671,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, } /* This is in document coordinates, i.e. pixels */ - if ( dbox && !dbox->isEmpty() ) { + if ( dbox ) { NRGC gc(NULL); /* Update to renderable state */ double sf = 1.0; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index af1883916..e6929fcff 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -68,8 +68,8 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) int prefs_bbox = prefs->getInt("/tools/bounding_box", 0); SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<Geom::Rect> const bbox(sel->bounds(bbox_type)); - if ( bbox && !bbox->isEmpty() ) { + Geom::OptRect const bbox(sel->bounds(bbox_type)); + if ( bbox ) { UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker")); SPUnit const &unit = *tracker->getActiveUnit(); @@ -159,9 +159,9 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) int prefs_bbox = prefs->getInt("/tools/bounding_box"); SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<Geom::Rect> bbox = selection->bounds(bbox_type); + Geom::OptRect bbox = selection->bounds(bbox_type); - if ( !bbox || bbox->isEmpty() ) { + if ( !bbox ) { g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index b945765db..ca6a72ca2 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -32,85 +32,74 @@ #include <gtk/gtk.h> #include <iostream> #include <sstream> - -#include "widgets/button.h" -#include "widgets/widget-sizes.h" -#include "widgets/spw-utilities.h" -#include "widgets/spinbutton-events.h" -#include "dialogs/text-edit.h" -#include "dialogs/dialog-events.h" - -#include "ui/widget/style-swatch.h" - -#include "verbs.h" -#include "sp-namedview.h" -#include "desktop.h" -#include "desktop-handles.h" -#include "xml/repr.h" -#include "xml/node-event-vector.h" -#include "xml/attribute-record.h" #include <glibmm/i18n.h> -#include "helper/unit-menu.h" -#include "helper/units.h" -#include "live_effects/effect.h" - -#include "inkscape.h" -#include "conn-avoid-ref.h" - -#include "select-toolbar.h" +#include "../box3d-context.h" +#include "../box3d.h" +#include "calligraphic-profile-rename.h" +#include "../conn-avoid-ref.h" +#include "../connection-pool.h" +#include "../connector-context.h" +#include "../desktop.h" +#include "../desktop-handles.h" +#include "../desktop-style.h" +#include "../dialogs/dialog-events.h" +#include "../dialogs/text-edit.h" +#include "../document-private.h" +#include "../ege-adjustment-action.h" +#include "../ege-output-action.h" +#include "../ege-select-one-action.h" +#include "../flood-context.h" #include "gradient-toolbar.h" - -#include "connector-context.h" -#include "node-context.h" -#include "pen-context.h" -#include "lpe-tool-context.h" -#include "live_effects/lpe-line_segment.h" -#include "shape-editor.h" -#include "tweak-context.h" -#include "sp-rect.h" -#include "box3d.h" -#include "box3d-context.h" -#include "sp-star.h" -#include "sp-spiral.h" -#include "sp-ellipse.h" -#include "sp-text.h" -#include "sp-flowtext.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "style.h" -#include "tools-switch.h" -#include "selection.h" -#include "selection-chemistry.h" -#include "document-private.h" -#include "desktop-style.h" -#include "../libnrtype/font-lister.h" +#include "../graphlayout/graphlayout.h" +#include "../helper/unit-menu.h" +#include "../helper/units.h" +#include "../helper/unit-tracker.h" +#include "icon.h" +#include "../ink-action.h" +#include "../inkscape.h" +#include "../inkscape-stock.h" +#include "../interface.h" #include "../libnrtype/font-instance.h" -#include "../connection-pool.h" +#include "../libnrtype/font-lister.h" +#include "../live_effects/effect.h" +#include "../live_effects/lpe-angle_bisector.h" +#include "../live_effects/lpe-line_segment.h" +#include "../lpe-tool-context.h" +#include "../mod360.h" +#include "../node-context.h" +#include "../pen-context.h" #include "../preferences.h" -#include "../inkscape-stock.h" -#include "icon.h" -#include "graphlayout/graphlayout.h" -#include "interface.h" -#include "shortcuts.h" - -#include "mod360.h" +#include "../selection-chemistry.h" +#include "../selection.h" +#include "select-toolbar.h" +#include "../shape-editor.h" +#include "../shortcuts.h" +#include "../sp-clippath.h" +#include "../sp-ellipse.h" +#include "../sp-flowtext.h" +#include "../sp-mask.h" +#include "../sp-namedview.h" +#include "../sp-rect.h" +#include "../sp-spiral.h" +#include "../sp-star.h" +#include "../sp-text.h" +#include "../style.h" +#include "../svg/css-ostringstream.h" +#include "../tools-switch.h" +#include "../tweak-context.h" +#include "../ui/widget/style-swatch.h" +#include "../verbs.h" +#include "../widgets/button.h" +#include "../widgets/spinbutton-events.h" +#include "../widgets/spw-utilities.h" +#include "../widgets/widget-sizes.h" +#include "../xml/attribute-record.h" +#include "../xml/node-event-vector.h" +#include "../xml/repr.h" #include "toolbox.h" -#include "flood-context.h" - -#include "ink-action.h" -#include "ege-adjustment-action.h" -#include "ege-output-action.h" -#include "ege-select-one-action.h" -#include "helper/unit-tracker.h" -#include "live_effects/lpe-angle_bisector.h" - -#include "svg/css-ostringstream.h" - -#include "widgets/calligraphic-profile-rename.h" - using Inkscape::UnitTracker; typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop); @@ -4106,6 +4095,7 @@ static void sp_dcc_build_presets_list(GObject *tbl) static void sp_dcc_save_profile (GtkWidget */*widget*/, GObject *tbl) { + using Inkscape::UI::Dialog::CalligraphicProfileRename; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop" ); if (! desktop) return; @@ -4113,13 +4103,13 @@ static void sp_dcc_save_profile (GtkWidget */*widget*/, GObject *tbl) if (g_object_get_data(tbl, "presets_blocked")) return; - Inkscape::UI::Dialogs::CalligraphicProfileDialog::show(desktop); - if ( ! Inkscape::UI::Dialogs::CalligraphicProfileDialog::applied()) { + CalligraphicProfileRename::show(desktop); + if ( !CalligraphicProfileRename::applied()) { // dialog cancelled update_presets_list (tbl); return; } - Glib::ustring profile_name = Inkscape::UI::Dialogs::CalligraphicProfileDialog::getProfileName(); + Glib::ustring profile_name = CalligraphicProfileRename::getProfileName(); if (profile_name.empty()) { // empty name entered @@ -5007,7 +4997,7 @@ lpetool_toggle_set_bbox (GtkToggleAction *act, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); Inkscape::Selection *selection = desktop->selection; - boost::optional<Geom::Rect> bbox = selection->bounds(); + Geom::OptRect bbox = selection->bounds(); if (bbox) { Geom::Point A(bbox->min()); diff --git a/src/zoom-context.cpp b/src/zoom-context.cpp index b00845077..2f0185731 100644 --- a/src/zoom-context.cpp +++ b/src/zoom-context.cpp @@ -176,7 +176,7 @@ static gint sp_zoom_context_root_handler(SPEventContext *event_context, GdkEvent Geom::Point const button_w(event->button.x, event->button.y); Geom::Point const button_dt(desktop->w2d(button_w)); if ( event->button.button == 1 && !event_context->space_panning) { - boost::optional<Geom::Rect> const b = Inkscape::Rubberband::get(desktop)->getRectangle(); + Geom::OptRect const b = Inkscape::Rubberband::get(desktop)->getRectangle(); if (b && !within_tolerance) { desktop->set_display_area(*b, 10); } else if (!escaped) { |
