diff options
| author | Johan B. C. Engelen <jbc.engelen@swissonline.ch> | 2014-01-12 23:25:39 +0000 |
|---|---|---|
| committer | Johan B. C. Engelen <j.b.c.engelen@alumnus.utwente.nl> | 2014-01-12 23:25:39 +0000 |
| commit | 5eb9b4815a12cc0dafd07905f7715a7e15a92b41 (patch) | |
| tree | f39f5ae5a40012fa010402611d2b133553c22335 /src | |
| parent | LPE: rename function getHelperPaths --> getCanvasIndicators (the function is ... (diff) | |
| download | inkscape-5eb9b4815a12cc0dafd07905f7715a7e15a92b41.tar.gz inkscape-5eb9b4815a12cc0dafd07905f7715a7e15a92b41.zip | |
update 2geom's copy to r2142
(bzr r12921)
Diffstat (limited to 'src')
50 files changed, 454 insertions, 296 deletions
diff --git a/src/2geom/Makefile_insert b/src/2geom/Makefile_insert index 07e066df5..e77f413cb 100644 --- a/src/2geom/Makefile_insert +++ b/src/2geom/Makefile_insert @@ -71,6 +71,8 @@ 2geom/path.h \ 2geom/path-intersection.cpp \ 2geom/path-intersection.h \ + 2geom/path-sink.cpp \ + 2geom/path-sink.h \ 2geom/pathvector.cpp \ 2geom/pathvector.h \ 2geom/piecewise.cpp \ @@ -110,8 +112,6 @@ 2geom/solver.h \ 2geom/svg-elliptical-arc.cpp \ 2geom/svg-elliptical-arc.h \ - 2geom/svg-path.cpp \ - 2geom/svg-path.h \ 2geom/svg-path-parser.cpp \ 2geom/svg-path-parser.h \ 2geom/sweep.cpp \ diff --git a/src/2geom/affine.cpp b/src/2geom/affine.cpp index 0ef6d2708..738d0fc48 100644 --- a/src/2geom/affine.cpp +++ b/src/2geom/affine.cpp @@ -454,8 +454,7 @@ Eigen::Eigen(Affine const &m) { } } -static void quadratic_roots(double q0, double q1, double q2, int &n, double&r0, double&r1) { - std::vector<double> r; +static void quadratic_roots(const double q0, const double q1, const double q2, int &n, double&r0, double&r1) { if(q2 == 0) { if(q1 == 0) { // zero or infinite roots n = 0; diff --git a/src/2geom/affine.h b/src/2geom/affine.h index b17da1887..af7b39360 100644 --- a/src/2geom/affine.h +++ b/src/2geom/affine.h @@ -75,12 +75,6 @@ public: _c[1] = _c[2] = _c[4] = _c[5] = 0; } - Affine(Affine const &m) { - for(int i = 0; i < 6; i++) { - _c[i] = m[i]; - } - } - /** @brief Create a matrix from its coefficient values. * It's rather inconvenient to directly create matrices in this way. Use transform classes * if your transformation has a geometric interpretation. @@ -88,19 +82,14 @@ public: * @see Scale * @see Rotate * @see HShear - * @see VShear */ + * @see VShear + * @see Zoom */ Affine(Coord c0, Coord c1, Coord c2, Coord c3, Coord c4, Coord c5) { _c[0] = c0; _c[1] = c1; _c[2] = c2; _c[3] = c3; _c[4] = c4; _c[5] = c5; } - Affine &operator=(Affine const &m) { - for(int i = 0; i < 6; i++) - _c[i] = m._c[i]; - return *this; - } - /** @brief Access a coefficient by its index. */ inline Coord operator[](unsigned i) const { return _c[i]; } inline Coord &operator[](unsigned i) { return _c[i]; } diff --git a/src/2geom/angle.h b/src/2geom/angle.h index bdf546989..1faf63c3f 100644 --- a/src/2geom/angle.h +++ b/src/2geom/angle.h @@ -48,6 +48,9 @@ namespace Geom { #ifndef M_PI # define M_PI 3.14159265358979323846 #endif +#ifndef M_1_2PI +# define M_1_2PI 0.159154943091895335768883763373 +#endif /** @brief Wrapper for angular values. * @@ -64,6 +67,7 @@ class Angle > > { public: + Angle() : _angle(0) {} //added default constructor because of cython Angle(Coord v) : _angle(v) { _normalize(); } // this can be called implicitly explicit Angle(Point p) : _angle(atan2(p)) { _normalize(); } Angle(Point a, Point b) : _angle(angle_between(a, b)) { _normalize(); } @@ -85,7 +89,7 @@ public: /** @brief Get the angle as radians. * @return Number in range \f$[-\pi, \pi)\f$. */ Coord radians() const { - return _angle > M_PI ? _angle - 2*M_PI : _angle; + return _angle >= M_PI ? _angle - 2*M_PI : _angle; } /** @brief Get the angle as positive radians. * @return Number in range \f$[0, 2\pi)\f$. */ @@ -95,7 +99,7 @@ public: /** @brief Get the angle as degrees in math convention. * @return Number in range [-180, 180) obtained by scaling the result of radians() * by \f$180/\pi\f$. */ - Coord degrees() const { return radians() / M_PI * 180.0; } + Coord degrees() const { return radians() * (180.0 / M_PI); } /** @brief Get the angle as degrees in clock convention. * This method converts the angle to the "clock convention": angles start from the +Y axis * and grow clockwise. This means that 0 corresponds to \f$\pi/2\f$ radians, @@ -103,7 +107,7 @@ public: * @return A number in the range [0, 360). */ Coord degreesClock() const { - Coord ret = 90.0 - _angle / M_PI * 180.0; + Coord ret = 90.0 - _angle * (180.0 / M_PI); if (ret < 0) ret += 360; return ret; } @@ -114,7 +118,7 @@ public: } /** @brief Create an angle from its measure in degrees. */ static Angle from_degrees(Coord d) { - Angle a(d * M_PI / 180); + Angle a(d * (M_PI / 180.0)); return a; } /** @brief Create an angle from its measure in degrees in clock convention. @@ -123,16 +127,16 @@ public: // first make sure d is in [0, 360) d = std::fmod(d, 360.0); if (d < 0) d += 360.0; - Coord rad = M_PI/2 - d * M_PI / 180.0; + Coord rad = M_PI/2 - d * (M_PI / 180.0); if (rad < 0) rad += 2*M_PI; Angle a; a._angle = rad; return a; } private: - Angle() {} + void _normalize() { - _angle -= floor(_angle / (2*M_PI)) * 2*M_PI; + _angle -= floor(_angle * (1.0/(2*M_PI))) * 2*M_PI; } Coord _angle; // this is always in [0, 2pi) friend class AngleInterval; diff --git a/src/2geom/basic-intersection.cpp b/src/2geom/basic-intersection.cpp index 544bf0dd1..379ec597c 100644 --- a/src/2geom/basic-intersection.cpp +++ b/src/2geom/basic-intersection.cpp @@ -64,15 +64,13 @@ void find_intersections(std::vector< std::pair<double, double> > & xs, void split(vector<Point> const &p, double t, vector<Point> &left, vector<Point> &right) { const unsigned sz = p.size(); - - Geom::Point **Vtemp = new Geom::Point* [sz]; - - for (unsigned int i = 0; i < sz; ++i) { - Vtemp[i] = new Geom::Point[sz]; - } + //Geom::Point Vtemp[sz][sz]; + vector<vector<Point> > Vtemp(sz); + for ( size_t i = 0; i < sz; ++i ) + Vtemp[i].reserve(sz); /* Copy control points */ - std::copy(p.begin(), p.end(), Vtemp[0]); + std::copy(p.begin(), p.end(), Vtemp[0].begin()); /* Triangle computation */ for (unsigned i = 1; i < sz; i++) { @@ -87,11 +85,6 @@ void split(vector<Point> const &p, double t, left[j] = Vtemp[j][0]; for (unsigned j = 0; j < sz; j++) right[j] = Vtemp[sz-1-j][j]; - - for (unsigned int i = 0; i < sz; ++i) - delete[] Vtemp[i]; - - delete[] Vtemp; } diff --git a/src/2geom/bezier-clipping.cpp b/src/2geom/bezier-clipping.cpp index fe925cf28..9a055204f 100644 --- a/src/2geom/bezier-clipping.cpp +++ b/src/2geom/bezier-clipping.cpp @@ -473,10 +473,9 @@ void fat_line_bounds (Interval& bound, { bound[0] = 0; bound[1] = 0; - double d; for (size_t i = 0; i < c.size(); ++i) { - d = distance(c[i], l); + const double d = distance(c[i], l); if (bound[0] > d) bound[0] = d; if (bound[1] < d) bound[1] = d; } @@ -509,10 +508,9 @@ void clip_interval (Interval& dom, double n = B.size() - 1; // number of sub-intervals std::vector<Point> D; // distance curve control points D.reserve (B.size()); - double d; for (size_t i = 0; i < B.size(); ++i) { - d = distance (B[i], l); + const double d = distance (B[i], l); D.push_back (Point(i/n, d)); } //print(D); @@ -699,8 +697,8 @@ void distance_control_points (std::vector<Point> & D, for (size_t j = 0; j < F.size(); ++j) dBF(i,j) = dot (dB[i], F[j]); - size_t k0, kn, l; - double bc, bri; + size_t l; + double bc; Point dij; std::vector<double> d(F.size()); for (size_t i = 0; i <= r; ++i) @@ -709,9 +707,9 @@ void distance_control_points (std::vector<Point> & D, { d[j] = 0; } - k0 = std::max(i, n) - n; - kn = std::min(i, n-1); - bri = n / binomial(r,i); + const size_t k0 = std::max(i, n) - n; + const size_t kn = std::min(i, n-1); + const double bri = n / binomial(r,i); for (size_t k = k0; k <= kn; ++k) { //if (k > i || (i-k) > n) continue; diff --git a/src/2geom/bezier-utils.cpp b/src/2geom/bezier-utils.cpp index af07db707..ec17f6869 100644 --- a/src/2geom/bezier-utils.cpp +++ b/src/2geom/bezier-utils.cpp @@ -194,8 +194,6 @@ bezier_fit_cubic_full(Point bezier[], int split_points[], Point const &tHat1, Point const &tHat2, double const error, unsigned const max_beziers) { - int const maxIterations = 4; /* std::max times to try iterating */ - if(!(bezier != NULL) || !(data != NULL) || !(len > 0) || @@ -257,6 +255,7 @@ bezier_fit_cubic_full(Point bezier[], int split_points[], /* If error not too large, then try some reparameterization and iteration. */ if ( 0.0 <= maxErrorRatio && maxErrorRatio <= 3.0 ) { + int const maxIterations = 4; /* std::max times to try iterating */ for (int i = 0; i < maxIterations; i++) { generate_bezier(bezier, data, u, len, tHat1, tHat2, error); reparameterize(data, len, u, bezier); diff --git a/src/2geom/circle.cpp b/src/2geom/circle.cpp index 06eb4c2a1..d021882ea 100644 --- a/src/2geom/circle.cpp +++ b/src/2geom/circle.cpp @@ -88,7 +88,9 @@ void Circle::set(std::vector<Point> const& points) model.instance(*this, fitter.result(z)); } - +/** + @param inner a point whose angle with the circle center is inside the angle that the arc spans + */ EllipticalArc * Circle::arc(Point const& initial, Point const& inner, Point const& final, bool _svg_compliant) @@ -98,10 +100,8 @@ Circle::arc(Point const& initial, Point const& inner, Point const& final, return e.arc(initial, inner, final, _svg_compliant); } -void -Circle::getPath(std::vector<Path> &path_out) { - Path pb; - +D2<SBasis> Circle::toSBasis() +{ D2<SBasis> B; Linear bo = Linear(0, 2 * M_PI); @@ -110,6 +110,15 @@ Circle::getPath(std::vector<Path> &path_out) { B = B * m_ray + m_centre; + return B; +} + +void +Circle::getPath(std::vector<Path> &path_out) { + Path pb; + + D2<SBasis> B = toSBasis(); + pb.append(SBasisCurve(B)); path_out.push_back(pb); diff --git a/src/2geom/circle.h b/src/2geom/circle.h index 67a638437..ca9241047 100644 --- a/src/2geom/circle.h +++ b/src/2geom/circle.h @@ -89,6 +89,7 @@ class Circle arc(Point const& initial, Point const& inner, Point const& final, bool _svg_compliant = true); + D2<SBasis> toSBasis(); void getPath(std::vector<Path> &path_out); Point center() const diff --git a/src/2geom/conicsec.cpp b/src/2geom/conicsec.cpp index 7625df2fb..367dc2503 100644 --- a/src/2geom/conicsec.cpp +++ b/src/2geom/conicsec.cpp @@ -211,8 +211,6 @@ RatQuad RatQuad::fromPointsTangents(Point P0, Point dP0, } RatQuad RatQuad::circularArc(Point P0, Point P1, Point P2) { - Line Line0 = Line::from_origin_and_versor(P0, P1 - P0); - Line Line2 = Line::from_origin_and_versor(P2, P1 - P2); return RatQuad(P0, P1, P2, dot(unit_vector(P0 - P1), unit_vector(P0 - P2))); } @@ -583,7 +581,7 @@ xAx xAx::operator*(double const &b) const { LineSegment ls = intersection(Line::from_origin_and_versor(A, dA), bnd); return RatQuad::fromPointsTangents(A, dA, ls.pointAt(0.5), ls[1], dA); } - else if(crs.size() >= 2 and crs.size() < 4) { + else if(crs.size() >= 2 && crs.size() < 4) { Point A = crs[0]; Point C = crs[1]; if(crs.size() == 3) { @@ -607,7 +605,7 @@ xAx xAx::operator*(double const &b) const { Point dA = gradient(A); Point dC = gradient(C); - if(L2sq(dA) <= 1e-10 or L2sq(dC) <= 1e-10) { + if(L2sq(dA) <= 1e-10 || L2sq(dC) <= 1e-10) { return RatQuad::fromPointsTangents(A, C-A, B, C, A-C); } @@ -710,7 +708,7 @@ boost::optional<Point> xAx::bottom() const { } Interval xAx::extrema(Rect r) const { - if (c[0] == 0 and c[1] == 0 and c[2] == 0) { + if (c[0] == 0 && c[1] == 0 && c[2] == 0) { Interval ext(valueAt(r.corner(0))); for(int i = 1; i < 4; i++) ext |= Interval(valueAt(r.corner(i))); @@ -725,7 +723,7 @@ Interval xAx::extrema(Rect r) const { k = r[1][1]; ext |= quad_ex(c[0], c[1]*k+c[3], (c[2]*k + c[4])*k + c[5], r[0]); boost::optional<Point> B0 = bottom(); - if (B0 and r.contains(*B0)) + if (B0 && r.contains(*B0)) ext.expandTo(0); return ext; } diff --git a/src/2geom/convex-cover.cpp b/src/2geom/convex-cover.cpp index 306060f7c..5e599fdde 100644 --- a/src/2geom/convex-cover.cpp +++ b/src/2geom/convex-cover.cpp @@ -433,7 +433,7 @@ bool same_side(Point L[2], Point xs[4]) { int side = 0; for(int i = 0; i < 4; i++) { int sn = sgn(SignedTriangleArea(L[0], L[1], xs[i])); - if(sn and not side) + if(sn && !side) side = sn; else if(sn != side) return false; } @@ -455,7 +455,7 @@ std::vector<pair<int, int> > bridges(ConvexHull a, ConvexHull b) { double ap_angle = atan2(a[ai+1] - a[ai]); double bp_angle = atan2(b[bi+1] - b[bi]); Point L[2] = {a[ai], b[bi]}; - while(ai < int(a.size()) or bi < int(b.size())) { + while(ai < int(a.size()) || bi < int(b.size())) { if(ap_angle == bp_angle) { // In the case of parallel support lines, we must consider all four pairs of copodal points { @@ -478,7 +478,7 @@ std::vector<pair<int, int> > bridges(ConvexHull a, ConvexHull b) { bi++; bp_angle += angle_between(b[bi] - b[bi-1], b[bi+1] - b[bi]); L[1] = b[bi]; - //std::cout << "parallel\n"; + std::cout << "parallel\n"; } else if(ap_angle < bp_angle) { ai++; ap_angle += angle_between(a[ai] - a[ai-1], a[ai+1] - a[ai]); @@ -559,7 +559,7 @@ T idx_to_pair(pair<T, T> p, int idx) { ConvexHull merge(ConvexHull a, ConvexHull b) { ConvexHull ret; - //std::cout << "---\n"; + std::cout << "---\n"; std::vector<pair<int, int> > bpair = bridges(a, b); // Given our list of bridges {(pb1, qb1), ..., (pbk, qbk)} @@ -574,10 +574,10 @@ ConvexHull merge(ConvexHull a, ConvexHull b) { for(unsigned k = 0; k < bpair.size(); k++) { unsigned limit = idx_to_pair(bpair[k], state); - /*std::cout << bpair[k].first << " , " << bpair[k].second << "; " + std::cout << bpair[k].first << " , " << bpair[k].second << "; " << idx << ", " << limit << ", s: " << state - << " \n";*/ + << " \n"; while(idx <= limit) { ret.boundary.push_back(chs[state][idx++]); } @@ -681,7 +681,7 @@ Point const * ConvexHull::furthest(Point direction) const { // is currently n*O(furthest) double ConvexHull::narrowest_diameter(Point &a, Point &b, Point &c) { Point tb = boundary.back(); - double d = INFINITY; + double d = std::numeric_limits<double>::max(); for(unsigned i = 0; i < boundary.size(); i++) { Point tc = boundary[i]; Point n = -rot90(tb-tc); diff --git a/src/2geom/convex-cover.h b/src/2geom/convex-cover.h index a5f95a5fb..d290b7e80 100644 --- a/src/2geom/convex-cover.h +++ b/src/2geom/convex-cover.h @@ -84,8 +84,9 @@ public: public: ConvexHull() {} - ConvexHull(std::vector<Point> const & points) { - boundary = points; + ConvexHull(std::vector<Point> const & points) : + boundary (points) + { graham(); } @@ -163,7 +164,7 @@ unsigned find_bottom_right(ConvexHull const &a); /*** Arbitrary transform operator. * Take a convex hull and apply an arbitrary convexity preserving transform. - * we should be concerned about singular transforms here. + * we should be concerned about singular tranforms here. */ template <class T> ConvexHull operator*(ConvexHull const &p, T const &m) { ConvexHull pr; diff --git a/src/2geom/crossing.cpp b/src/2geom/crossing.cpp index 379eb4b00..13affa8e9 100644 --- a/src/2geom/crossing.cpp +++ b/src/2geom/crossing.cpp @@ -154,7 +154,7 @@ Crossings reverse_tb(Crossings const &cr, unsigned split, std::vector<double> ma Crossings ret; for(Crossings::const_iterator i = cr.begin(); i != cr.end(); ++i) { double mx = max[i->b - split]; - //std::cout << i->b << "\n"; + std::cout << i->b << "\n"; ret.push_back(Crossing(i->ta, i->tb > mx+0.01 ? (1 - (i->tb - mx) + mx) : mx - i->tb, !i->dir)); } diff --git a/src/2geom/d2.h b/src/2geom/d2.h index ef88b2d68..5fc955854 100644 --- a/src/2geom/d2.h +++ b/src/2geom/d2.h @@ -150,7 +150,7 @@ template <typename T> inline bool are_near(D2<T> const &a, D2<T> const &b, double tol) { boost::function_requires<NearConcept<T> >(); - return are_near(a[0], b[0]) && are_near(a[1], b[1]); + return are_near(a[0], b[0], tol) && are_near(a[1], b[1], tol); } //IMPL: AddableConcept diff --git a/src/2geom/ellipse.h b/src/2geom/ellipse.h index 297254366..c971c6065 100644 --- a/src/2geom/ellipse.h +++ b/src/2geom/ellipse.h @@ -49,7 +49,10 @@ class Circle; class Ellipse { public: - Ellipse() + Ellipse(): + m_centre(), + m_ray(), + m_angle(0) {} Ellipse(double cx, double cy, double rx, double ry, double a) diff --git a/src/2geom/elliptical-arc.cpp b/src/2geom/elliptical-arc.cpp index d2cb0b707..c96d5f1a6 100644 --- a/src/2geom/elliptical-arc.cpp +++ b/src/2geom/elliptical-arc.cpp @@ -115,9 +115,11 @@ Rect EllipticalArc::boundsExact() const if ( arc_extremes[2] < arc_extremes[3] ) std::swap(arc_extremes[2], arc_extremes[3]); - for (unsigned i = 0; i < 4; ++i) { - if (containsAngle(extremes[i])) { - arc_extremes[i] = valueAtAngle(extremes[i], (i >> 1) ? Y : X); + if ( !are_near(initialPoint(), finalPoint()) ) { + for (unsigned i = 0; i < 4; ++i) { + if (containsAngle(extremes[i])) { + arc_extremes[i] = valueAtAngle(extremes[i], (i >> 1) ? Y : X); + } } } @@ -264,7 +266,7 @@ std::vector<Coord> EllipticalArc::roots(Coord v, Dim2 d) const } double rotx, roty; - sincos(_rot_angle, roty, rotx); + sincos(_rot_angle, roty, rotx); /// \todo sin and cos are calculated in many places in this function, optimize this a bit! if (d == X) roty = -roty; double rxrotx = ray(X) * rotx; @@ -569,7 +571,7 @@ std::vector<double> EllipticalArc::allNearestPoints( Point const& p, double from double mindistsq1 = std::numeric_limits<double>::max(); double mindistsq2 = std::numeric_limits<double>::max(); double dsq; - unsigned int mi1, mi2; + unsigned int mi1 = 0, mi2 = 0; for ( unsigned int i = 0; i < real_sol.size(); ++i ) { dsq = distanceSq(p, pointAtAngle(real_sol[i])); diff --git a/src/2geom/generic-rect.h b/src/2geom/generic-rect.h index eb9705a4b..bb6f2d2b8 100644 --- a/src/2geom/generic-rect.h +++ b/src/2geom/generic-rect.h @@ -261,7 +261,7 @@ public: expandBy(amount, amount); } /** @brief Expand the rectangle in both directions. - * Note that this is different from scaling. Negative values will shrink the + * Note that this is different from scaling. Negative values wil shrink the * rectangle. If <code>-x</code> is larger than * half of the width, the X interval will contain only the X coordinate * of the midpoint; same for height. */ diff --git a/src/2geom/interval.h b/src/2geom/interval.h index b1fac04d9..1714435be 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -114,9 +114,9 @@ public: /** @brief Check whether the interior of the interval includes the given interval. * Interior means all numbers in the interval except its ends. */ bool interiorContains(Interval const &val) const { return min() < val.min() && val.max() < max(); } - /** @brief Check whether the interiors of the intervals have any common elements. */ + /** @brief Check whether the interiors of the intervals have any common elements. A single point in common is not considered an intersection. */ bool interiorIntersects(Interval const &val) const { - return interiorContains(val.min()) || interiorContains(val.max()) || val.interiorContains(*this); + return std::max(min(), val.min()) < std::min(max(), val.max()); } /// @} diff --git a/src/2geom/linear.h b/src/2geom/linear.h index 6e5132e12..8c154364e 100644 --- a/src/2geom/linear.h +++ b/src/2geom/linear.h @@ -55,7 +55,7 @@ class SBasis; class Linear{ public: double a[2]; - Linear() {} + Linear() {a[0]=0; a[1]=0;} Linear(double aa, double b) {a[0] = aa; a[1] = b;} Linear(double aa) {a[0] = aa; a[1] = aa;} diff --git a/src/2geom/math-utils.h b/src/2geom/math-utils.h index 77280aa50..83c7b4f5e 100644 --- a/src/2geom/math-utils.h +++ b/src/2geom/math-utils.h @@ -40,6 +40,7 @@ #include <math.h> // sincos is usually only available in math.h #include <cmath> #include <utility> // for std::pair +#include <boost/math/special_functions/fpclassify.hpp> namespace Geom { @@ -49,6 +50,8 @@ namespace Geom { * @return -1 when x is negative, 1 when positive, and 0 if equal to 0. */ template <class T> inline int sgn(const T& x) { return (x < 0 ? -1 : (x > 0 ? 1 : 0) ); +// can we 'optimize' this with: +// return ( (T(0) < x) - (x < T(0)) ); } template <class T> inline T sqr(const T& x) {return x * x;} @@ -111,7 +114,7 @@ inline void sincos(double angle, double &sin_, double &cos_) { #elif defined (SOLARIS_2_8) && __GNUC__ == 3 && __GNUC_MINOR__ == 2 # define IS_NAN(_a) (isnan(_a)) /* GNU definition */ #else -# define IS_NAN(_a) (std::isnan(_a)) +# define IS_NAN(_a) (boost::math::isnan(_a)) #endif /* If the above doesn't work, then try (a != a). */ @@ -130,7 +133,7 @@ inline void sincos(double angle, double &sin_, double &cos_) { #include <ieeefp.h> #define IS_FINITE(_a) (finite(_a) && !IS_NAN(_a)) #else -# define IS_FINITE(_a) (std::isfinite(_a)) +# define IS_FINITE(_a) (boost::math::isfinite(_a)) #endif } // end namespace Geom diff --git a/src/2geom/nearest-point.cpp b/src/2geom/nearest-point.cpp index 68a863434..75e1ebaad 100644 --- a/src/2geom/nearest-point.cpp +++ b/src/2geom/nearest-point.cpp @@ -61,15 +61,14 @@ double nearest_point( Point const& p, } if (c.isConstant()) return from; SBasis dd = dot(c - p, dc); - //std::cout << dd << std::endl; + std::cout << dd << std::endl; 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 ) + for ( size_t i = 0; i < zeros.size(); ++i ) { - distsq = L2sq(c(zeros[i]) - p); + double distsq = L2sq(c(zeros[i]) - p); if ( min_dist_sq > L2sq(c(zeros[i]) - p) ) { closest = zeros[i]; diff --git a/src/2geom/ord.h b/src/2geom/ord.h index ce524ebf7..0add83da4 100644 --- a/src/2geom/ord.h +++ b/src/2geom/ord.h @@ -43,7 +43,7 @@ enum Cmp { EQUAL_TO=0 }; -inline Cmp operator-(Cmp x) { +static inline Cmp operator-(Cmp x) { switch(x) { case LESS_THAN: return GREATER_THAN; diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index 494a25843..ff24b92eb 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -113,11 +113,12 @@ int winding(Path const &path, Point p) { */ bool path_direction(Path const &p) { if(p.empty()) return false; + + /*goto doh; //could probably be more efficient, but this is a quick job double y = p.initialPoint()[Y]; double x = p.initialPoint()[X]; Cmp res = cmp(p[0].finalPoint()[Y], y); - /*goto doh; for(unsigned i = 1; i < p.size(); i++) { Cmp final_to_ray = cmp(p[i].finalPoint()[Y], y); Cmp initial_to_ray = cmp(p[i].initialPoint()[Y], y); @@ -271,9 +272,9 @@ intersect_polish_root (Curve const &A, double &s, Curve const &B, double &t) } #ifdef HAVE_GSL - int status; - size_t iter = 0; if(0) { // the GSL version is more accurate, but taints this with GPL + int status; + size_t iter = 0; const size_t n = 2; struct rparams p = {A, B}; gsl_multiroot_function f = {&intersect_polish_f, n, &p}; diff --git a/src/2geom/svg-path.cpp b/src/2geom/path-sink.cpp index d459b3e1b..6acd9508c 100644 --- a/src/2geom/svg-path.cpp +++ b/src/2geom/path-sink.cpp @@ -29,45 +29,45 @@ */ #include <2geom/sbasis-to-bezier.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <2geom/exception.h> namespace Geom { -void output(Curve const &curve, SVGPathSink &sink) { +void output(Curve const &curve, PathSink &sink) { std::vector<Point> pts; sbasis_to_bezier(pts, curve.toSBasis(), 2); //TODO: use something better! sink.curveTo(pts[0], pts[1], pts[2]); } -void output(HLineSegment const &curve, SVGPathSink &sink) { +void output(HLineSegment const &curve, PathSink &sink) { sink.hlineTo(curve.finalPoint()[X]); } -void output(VLineSegment const &curve, SVGPathSink &sink) { +void output(VLineSegment const &curve, PathSink &sink) { sink.vlineTo(curve.finalPoint()[Y]); } -void output(LineSegment const &curve, SVGPathSink &sink) { +void output(LineSegment const &curve, PathSink &sink) { sink.lineTo(curve[1]); } -void output(CubicBezier const &curve, SVGPathSink &sink) { +void output(CubicBezier const &curve, PathSink &sink) { sink.curveTo(curve[1], curve[2], curve[3]); } -void output(QuadraticBezier const &curve, SVGPathSink &sink) { +void output(QuadraticBezier const &curve, PathSink &sink) { sink.quadTo(curve[1], curve[2]); } -void output(SVGEllipticalArc const &curve, SVGPathSink &sink) { +void output(SVGEllipticalArc const &curve, PathSink &sink) { sink.arcTo( curve.ray(X), curve.ray(Y), curve.rotationAngle(), curve.largeArc(), curve.sweep(), curve.finalPoint() ); } template <typename T> -bool output_as(Curve const &curve, SVGPathSink &sink) { +bool output_as(Curve const &curve, PathSink &sink) { T const *t = dynamic_cast<T const *>(&curve); if (t) { output(*t, sink); @@ -77,24 +77,32 @@ bool output_as(Curve const &curve, SVGPathSink &sink) { } } -void output_svg_path(Path &path, SVGPathSink &sink) { - sink.moveTo(path.front().initialPoint()); - - Path::iterator iter; - for ( iter = path.begin() ; iter != path.end() ; ++iter ) { - output_as<HLineSegment>(*iter, sink) || - output_as<VLineSegment>(*iter, sink) || - output_as<LineSegment>(*iter, sink) || - output_as<CubicBezier>(*iter, sink) || - output_as<QuadraticBezier>(*iter, sink) || - output_as<SVGEllipticalArc>(*iter, sink) || - output_as<Curve>(*iter, sink); +void PathSink::path(Path const &path) { + flush(); + moveTo(path.front().initialPoint()); + + Path::const_iterator iter; + for (iter = path.begin(); iter != path.end(); ++iter) { + output_as<HLineSegment>(*iter, *this) || + output_as<VLineSegment>(*iter, *this) || + output_as<LineSegment>(*iter, *this) || + output_as<CubicBezier>(*iter, *this) || + output_as<QuadraticBezier>(*iter, *this) || + output_as<SVGEllipticalArc>(*iter, *this) || + output_as<Curve>(*iter, *this); } if (path.closed()) { - sink.closePath(); + closePath(); + } + flush(); +} + +void PathSink::pathvector(PathVector const &pv) { + flush(); + for (PathVector::const_iterator i = pv.begin(); i != pv.end(); ++i) { + path(*i); } - sink.finish(); } } diff --git a/src/2geom/svg-path.h b/src/2geom/path-sink.h index c22f65d11..949369b80 100644 --- a/src/2geom/svg-path.h +++ b/src/2geom/path-sink.h @@ -1,7 +1,7 @@ /** * \file * \brief callback interface for SVG path data - * + *//* * Copyright 2007 MenTaLguY <mental@rydia.net> * * This library is free software; you can redistribute it and/or @@ -32,41 +32,78 @@ #ifndef SEEN_SVG_PATH_H #define SEEN_SVG_PATH_H -#include <2geom/path.h> +#include <2geom/pathvector.h> #include <2geom/curves.h> #include <iterator> namespace Geom { -class SVGPathSink { + +/** @brief Callback interface for processing path data. + * + * PathSink provides an interface that allows one to easily write + * code which processes path data, for instance when converting + * between path formats used by different graphics libraries. + * + * To store a path in a new format, implement the virtual methods + * for segments in a derived class and call path() or pathvector(). + */ +class PathSink { public: - virtual void moveTo(Point p) = 0; + /** Move to a different point without creating a segment. + * Usually starts a new subpath. */ + virtual void moveTo(Point const &p) = 0; + /// Output a horizontal line segment. Only the X coordinate of the final point is given. virtual void hlineTo(Coord v) = 0; + /// Output a vertical line segment. Only the Y coordinate of the final point is given. virtual void vlineTo(Coord v) = 0; - virtual void lineTo(Point p) = 0; - virtual void curveTo(Point c0, Point c1, Point p) = 0; - virtual void quadTo(Point c, Point p) = 0; + /// Output a line segment. + virtual void lineTo(Point const &p) = 0; + /// Output a quadratic Bezier segment. + virtual void curveTo(Point const &c0, Point const &c1, Point const &p) = 0; + /// Output a cubic Bezier segment. + virtual void quadTo(Point const &c, Point const &p) = 0; + /** Output an elliptical arc segment. + * See the EllipticalArc class for the documentation of parameters. */ virtual void arcTo(double rx, double ry, double angle, - bool large_arc, bool sweep, Point p) = 0; - - /** Undo the last lineTo, curveTo, etc. call. */ - virtual void backspace() = 0; + bool large_arc, bool sweep, Point const &p) = 0; + /// Close the current path with a line segment. virtual void closePath() = 0; - virtual void finish() = 0; - virtual ~SVGPathSink() {} + /** Flush any internal state of the generator. + * + * This call should implicitly finish the current subpath. + * Calling this method should be idempotent, because the default + * implementations of path() and pathvector() will be call it + * multiple times in a row. */ + virtual void flush() = 0; + + /** Undo the last segment. + * This method is optional. + * @return true true if a segment was erased, false otherwise. */ + virtual bool backspace() { return false; } + + // these have a default implementation + /** Output a subpath. + * Calls the appropriate segment methods according to the contents + * of the passed subpath. You can override this function. */ + virtual void path(Path const &p); + /** Output a path. + * Calls the appropriate segment methods according to the contents + * of the passed path. You can override this function. */ + virtual void pathvector(PathVector const &v); + + virtual ~PathSink() {} }; -void output_svg_path(Path &path, SVGPathSink &sink); - template <typename OutputIterator> -class SVGPathGenerator : public SVGPathSink { +class PathIteratorSink : public PathSink { public: - explicit SVGPathGenerator(OutputIterator out) + explicit PathIteratorSink(OutputIterator out) : _in_path(false), _out(out) {} - void moveTo(Point p) { - finish(); + void moveTo(Point const &p) { + flush(); _path.start(p); _start_p = p; _in_path = true; @@ -89,7 +126,7 @@ public: _path.template appendNew<VLineSegment>(Point(_path.finalPoint()[X], v)); } - void lineTo(Point p) { + void lineTo(Point const &p) { // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z" if (!_in_path) { moveTo(_start_p); @@ -97,7 +134,7 @@ public: _path.template appendNew<LineSegment>(p); } - void quadTo(Point c, Point p) { + void quadTo(Point const &c, Point const &p) { // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z" if (!_in_path) { moveTo(_start_p); @@ -105,7 +142,7 @@ public: _path.template appendNew<QuadraticBezier>(c, p); } - void curveTo(Point c0, Point c1, Point p) { + void curveTo(Point const &c0, Point const &c1, Point const &p) { // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z" if (!_in_path) { moveTo(_start_p); @@ -114,7 +151,7 @@ public: } void arcTo(double rx, double ry, double angle, - bool large_arc, bool sweep, Point p) + bool large_arc, bool sweep, Point const &p) { // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z" if (!_in_path) { @@ -124,11 +161,13 @@ public: large_arc, sweep, p); } - void backspace() + bool backspace() { if (_in_path && _path.size() > 0) { _path.erase_last(); + return true; } + return false; } void append(Path const &other, Path::Stitching stitching = Path::NO_STITCHING) @@ -141,18 +180,24 @@ public: void closePath() { _path.close(); - finish(); + flush(); } - void finish() { + void flush() { if (_in_path) { _in_path = false; - *_out = _path; + *_out++ = _path; _path.clear(); _path.close(false); } } + void path(Path const &other) + { + flush(); + *_out++ = other; + } + protected: bool _in_path; OutputIterator _out; @@ -162,11 +207,11 @@ protected: typedef std::back_insert_iterator<std::vector<Path> > iter; -class PathBuilder : public SVGPathGenerator<iter> { +class PathBuilder : public PathIteratorSink<iter> { private: std::vector<Path> _pathset; public: - PathBuilder() : SVGPathGenerator<iter>(iter(_pathset)) {} + PathBuilder() : PathIteratorSink<iter>(iter(_pathset)) {} std::vector<Path> const &peek() const {return _pathset;} }; diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index 857028ccd..93def6c55 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -347,16 +347,15 @@ void Path::do_update(Sequence::iterator first_replaced, } void Path::do_append(Curve *c) { - boost::shared_ptr<Curve> curve(c); if ( get_curves().front().get() == final_ ) { - final_->setPoint(1, curve->initialPoint()); + final_->setPoint(1, c->initialPoint()); } else { - if (curve->initialPoint() != finalPoint()) { + if (c->initialPoint() != finalPoint()) { THROW_CONTINUITYERROR(); } } - get_curves().insert(get_curves().end()-1, curve); - final_->setPoint(0, curve->finalPoint()); + get_curves().insert(get_curves().end()-1, boost::shared_ptr<Curve>(c)); + final_->setPoint(0, c->finalPoint()); } void Path::stitch(Sequence::iterator first_replaced, diff --git a/src/2geom/pathvector.h b/src/2geom/pathvector.h index 791cb0703..e875e915f 100644 --- a/src/2geom/pathvector.h +++ b/src/2geom/pathvector.h @@ -108,7 +108,10 @@ struct PathVectorPosition { // pathvector[path_nr].pointAt(t) is the position unsigned int path_nr; double t; - PathVectorPosition() {} + PathVectorPosition() : + path_nr(0), + t(0) + {} PathVectorPosition(unsigned int path_nr, double t) : path_nr(path_nr), t(t) {} }; diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h index e3b4d3456..ab8417254 100644 --- a/src/2geom/piecewise.h +++ b/src/2geom/piecewise.h @@ -34,6 +34,7 @@ #include <vector> #include <map> +#include <utility> #include <boost/concept_check.hpp> #include <2geom/concepts.h> #include <2geom/math-utils.h> @@ -92,8 +93,8 @@ class Piecewise { inline void reserve(unsigned i) { segs.reserve(i); cuts.reserve(i + 1); } - inline T operator[](unsigned i) const { return segs[i]; } - inline T &operator[](unsigned i) { return segs[i]; } + inline T const& operator[](unsigned i) const { return segs[i]; } + inline T& operator[](unsigned i) { return segs[i]; } inline output_type operator()(double t) const { return valueAt(t); } inline output_type valueAt(double t) const { unsigned n = segN(t); @@ -139,6 +140,13 @@ class Piecewise { push_seg(s); push_cut(to); } +#ifdef CPP11 + inline void push(T &&s, double to) { + assert(cuts.size() - segs.size() == 1); + push_seg(s); + push_cut(to); + } +#endif //Convenience/implementation hiding function to add cuts. inline void push_cut(double c) { ASSERT_INVARIANTS(cuts.empty() || c > cuts.back()); @@ -146,6 +154,9 @@ class Piecewise { } //Convenience/implementation hiding function to add segments. inline void push_seg(const T &s) { segs.push_back(s); } +#ifdef CPP11 + inline void push_seg(T &&s) { segs.emplace_back(s); } +#endif /**Returns the segment index which corresponds to a 'global' piecewise time. * Also takes optional low/high parameters to expedite the search for the segment. diff --git a/src/2geom/point.cpp b/src/2geom/point.cpp index 3ad9dd1fd..b0b00b5da 100644 --- a/src/2geom/point.cpp +++ b/src/2geom/point.cpp @@ -57,11 +57,10 @@ namespace Geom { * @code p += q; p -= q; r = p + q; r = p - q; p *= s; p /= s; q = p * s; q = s * p; q = p / s; - p *= m; p /= m; q = p * m; q = m * p; q = p / m; + p *= m; q = p * m; q = m * p; @endcode * It is possible to left-multiply a point by a matrix, even though mathematically speaking * this is undefined. The result is a point identical to that obtained by right-multiplying. - * Division of points by matrices is defined as multiplication by their inverses. * * @ingroup Primitives */ @@ -127,7 +126,7 @@ Coord L1(Point const &p) { } /** @brief Compute the infinity norm (maximum norm) of @a p. - * @return \f$\max(p_X, p_Y)\f$ + * @return \f$\max(|p_X|, |p_Y|)\f$ * @relates Point */ Coord LInfty(Point const &p) { Coord const a(fabs(p[0])); @@ -231,7 +230,7 @@ Point constrain_angle(Point const &A, Point const &B, unsigned int n, Point cons return A + dir * Rotate(k * 2.0 * M_PI / (double)n) * L2(diff); } -} //namespace Geom +} // end namespace Geom /* Local Variables: diff --git a/src/2geom/point.h b/src/2geom/point.h index 0eb771874..23dcfd54f 100644 --- a/src/2geom/point.h +++ b/src/2geom/point.h @@ -78,15 +78,6 @@ public: _pt[X] = p[X]; _pt[Y] = p[Y]; } - Point(Point const &p) { - for (unsigned i = 0; i < 2; ++i) - _pt[i] = p._pt[i]; - } - Point &operator=(Point const &p) { - for (unsigned i = 0; i < 2; ++i) - _pt[i] = p._pt[i]; - return *this; - } /** @brief Construct a point from its polar coordinates. * The angle is specified in radians, in the mathematical convention (increasing * counter-clockwise from +X). */ diff --git a/src/2geom/recursive-bezier-intersection.cpp b/src/2geom/recursive-bezier-intersection.cpp index 7db0438a7..0c7977970 100644 --- a/src/2geom/recursive-bezier-intersection.cpp +++ b/src/2geom/recursive-bezier-intersection.cpp @@ -81,14 +81,13 @@ const double INV_EPS = (1L<<14); */ void OldBezier::split(double t, OldBezier &left, OldBezier &right) const { const unsigned sz = p.size(); - - Geom::Point **Vtemp = new Geom::Point* [sz]; - - for (unsigned int i = 0; i < sz; ++i) - Vtemp[i] = new Geom::Point[sz]; + //Geom::Point Vtemp[sz][sz]; + std::vector< std::vector< Geom::Point > > Vtemp; + for (size_t i = 0; i < sz; ++i ) + Vtemp[i].reserve(sz); /* Copy control points */ - std::copy(p.begin(), p.end(), Vtemp[0]); + std::copy(p.begin(), p.end(), Vtemp[0].begin()); /* Triangle computation */ for (unsigned i = 1; i < sz; i++) { @@ -103,11 +102,6 @@ void OldBezier::split(double t, OldBezier &left, OldBezier &right) const { left.p[j] = Vtemp[j][0]; for (unsigned j = 0; j < sz; j++) right.p[j] = Vtemp[sz-1-j][j]; - - for (unsigned int i = 0; i < sz; ++i) - delete[] Vtemp[i]; - - delete[] Vtemp; } #if 0 @@ -134,17 +128,15 @@ Point OldBezier::operator()(double t) const { #endif // suggested by Sederberg. -Point OldBezier::operator()(double t) const { - int n = p.size()-1; - double u, bc, tn, tmp; - int i; +Point OldBezier::operator()(double const t) const { + size_t const n = p.size()-1; Point r; for(int dim = 0; dim < 2; dim++) { - u = 1.0 - t; - bc = 1; - tn = 1; - tmp = p[0][dim]*u; - for(i=1; i<n; i++){ + double const u = 1.0 - t; + double bc = 1; + double tn = 1; + double tmp = p[0][dim]*u; + for(size_t i=1; i<n; i++){ tn = tn*t; bc = bc*(n-i+1)/i; tmp = (tmp + tn*bc*p[i][dim])*u; @@ -183,8 +175,8 @@ bool intersect_BB( OldBezier a, OldBezier b ) { b.bounds(minbx, maxbx, minby, maxby); // Test bounding box of b against bounding box of a // Not >= : need boundary case - return not( ( minax > maxbx ) || ( minay > maxby ) - || ( minbx > maxax ) || ( minby > maxay ) ); + return !( ( minax > maxbx ) || ( minay > maxby ) + || ( minbx > maxax ) || ( minby > maxay ) ); } /* diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index 74827e27c..4c474f7f0 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -1,4 +1,5 @@ /** Geometric operators on D2<SBasis> (1D->2D). + * Copyright 2012 JBC Engelen * Copyright 2007 JF Barraud * Copyright 2007 N Hurst * @@ -18,7 +19,6 @@ #include <2geom/sbasis-geometric.h> #include <2geom/sbasis.h> #include <2geom/sbasis-math.h> -//#include <2geom/solver.h> #include <2geom/sbasis-geometric.h> //namespace Geom{ @@ -363,7 +363,6 @@ Geom::length(Piecewise<D2<SBasis> > const &M, Piecewise<SBasis> Geom::curvature(D2<SBasis> const &M, double tol) { D2<SBasis> dM=derivative(M); - Piecewise<SBasis> result; Piecewise<D2<SBasis> > unitv = unitVector(dM,tol); Piecewise<SBasis> dMlength = dot(Piecewise<D2<SBasis> >(dM),unitv); Piecewise<SBasis> k = cross(derivative(unitv),unitv); @@ -436,11 +435,10 @@ Geom::arc_length_parametrization(Piecewise<D2<SBasis> > const &M, unsigned order, double tol){ Piecewise<D2<SBasis> > result; - for (unsigned i=0; i<M.size(); i++ ){ - Piecewise<D2<SBasis> > uniform_seg=arc_length_parametrization(M[i],order,tol); - result.concat(uniform_seg); + for (unsigned i=0; i<M.size(); i++) { + result.concat( arc_length_parametrization(M[i],order,tol) ); } - return(result); + return result; } #include <gsl/gsl_integration.h> diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp index 8e47580ce..bd88f93c0 100644 --- a/src/2geom/sbasis-to-bezier.cpp +++ b/src/2geom/sbasis-to-bezier.cpp @@ -35,7 +35,7 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/d2.h> #include <2geom/choose.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <2geom/exception.h> #include <iostream> @@ -180,6 +180,118 @@ void sbasis_to_bezier (std::vector<Point> & bz, D2<SBasis> const& sb, size_t sz) } } +/** Changes the basis of p to be Bernstein. + \param p the D2 Symmetric basis polynomial + \returns the D2 Bernstein basis cubic polynomial + +Bezier is always cubic. +For general asymmetric case, fit the SBasis function value at midpoint +For parallel, symmetric case, find the point of closest approach to the midpoint +For parallel, anti-symmetric case, fit the SBasis slope at midpoint +*/ +void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb) +{ + double delx[2], dely[2]; + double xprime[2], yprime[2]; + double midx = 0; + double midy = 0; + double numer; + double denom; + double div; + + if ((sb[X].size() == 0) || (sb[Y].size() == 0)) { + THROW_RANGEERROR("size of sb is too small"); + } + + bz.resize(4, Point(0,0)); + bz[0][X] = sb[X][0][0]; + bz[0][Y] = sb[Y][0][0]; + bz[3][X] = sb[X][0][1]; + bz[3][Y] = sb[Y][0][1]; + +// calculate first derivatives of x and y wrt t + + for (int i = 0; i < 2; ++i) { + xprime[i] = sb[X][0][1] - sb[X][0][0]; + yprime[i] = sb[Y][0][1] - sb[Y][0][0]; + } + if (sb[X].size() > 0) { + xprime[0] += sb[X][1][0]; + xprime[1] -= sb[X][1][1]; + } + if (sb[Y].size() > 0) { + yprime[0] += sb[Y][1][0]; + yprime[1] -= sb[Y][1][1]; + } + +// calculate midpoint at t = 0.5 + + div = 2; + for (size_t i = 0; i < sb[X].size(); ++i) { + midx += (sb[X][i][0] + sb[X][i][1])/div; + div *= 4; + } + midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; + + div = 2; + for (size_t i = 0; i < sb[Y].size(); ++i) { + midy += (sb[Y][i][0] + sb[Y][i][1])/div; + div *= 4; + } + midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y]; + +// calculate Bezier control arms + + if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > 1.e-5) { // general case : fit mid fxn value + denom = xprime[1]*yprime[0] - yprime[1]*xprime[0]; + for (int i = 0; i < 2; ++i) { + numer = xprime[1 - i]*midy - yprime[1 - i]*midx; + delx[i] = xprime[i]*numer/denom/3; + dely[i] = yprime[i]*numer/denom/3; + } + } + else if ((xprime[0]*xprime[1] < 0) || (yprime[0]*yprime[1] < 0)) { // symmetric case : use distance of closest approach + numer = midx*xprime[0] + midy*yprime[0]; + denom = 6.0*(xprime[0]*xprime[0] + yprime[0]*yprime[0]); + delx[0] = xprime[0]*numer/denom; + dely[0] = yprime[0]*numer/denom; + delx[1] = -delx[0]; + dely[1] = -dely[0]; + } + else { // anti-symmetric case : fit mid slope + // calculate slope at t = 0.5 + midx = 0; + div = 1; + for (size_t i = 0; i < sb[X].size(); ++i) { + midx += (sb[X][i][1] - sb[X][i][0])/div; + div *= 4; + } + midy = 0; + div = 1; + for (size_t i = 0; i < sb[Y].size(); ++i) { + midy += (sb[Y][i][1] - sb[Y][i][0])/div; + div *= 4; + } + if (midx*yprime[0] != midy*xprime[0]) { + denom = midx*yprime[0] - midy*xprime[0]; + numer = midx*(bz[3][Y] - bz[0][Y]) - midy*(bz[3][X] - bz[0][X]); + for (int i = 0; i < 2; ++i) { + delx[i] = xprime[0]*numer/denom; + dely[i] = yprime[0]*numer/denom; + } + } + else { // linear case + for (int i = 0; i < 2; ++i) { + delx[i] = (bz[3][X] - bz[0][X])/3; + dely[i] = (bz[3][Y] - bz[0][Y])/3; + } + } + } + bz[1][X] = bz[0][X] + delx[0]; + bz[1][Y] = bz[0][Y] + dely[0]; + bz[2][X] = bz[3][X] - delx[1]; + bz[2][Y] = bz[3][Y] - dely[1]; +} /** Changes the basis of p to be sbasis. \param p the Bernstein basis polynomial @@ -347,12 +459,13 @@ void build_from_sbasis(Geom::PathBuilder &pb, D2<SBasis> const &B, double tol, b if (!B.isFinite()) { THROW_EXCEPTION("assertion failed: B.isFinite()"); } - if(tail_error(B, 2) < tol || sbasis_size(B) == 2) { // nearly cubic enough + if(tail_error(B, 3) < tol || sbasis_size(B) == 2) { // nearly cubic enough if( !only_cubicbeziers && (sbasis_size(B) <= 1) ) { pb.lineTo(B.at1()); } else { std::vector<Geom::Point> bez; - sbasis_to_bezier(bez, B, 4); +// sbasis_to_bezier(bez, B, 4); + sbasis_to_cubic_bezier(bez, B); pb.curveTo(bez[1], bez[2], bez[3]); } } else { @@ -372,7 +485,7 @@ path_from_sbasis(D2<SBasis> const &B, double tol, bool only_cubicbeziers) { PathBuilder pb; pb.moveTo(B.at0()); build_from_sbasis(pb, B, tol, only_cubicbeziers); - pb.finish(); + pb.flush(); return pb.peek().front(); } @@ -414,7 +527,7 @@ path_from_piecewise(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &B, double to build_from_sbasis(pb, B[i], tol, only_cubicbeziers); } } - pb.finish(); + pb.flush(); return pb.peek(); } diff --git a/src/2geom/sbasis-to-bezier.h b/src/2geom/sbasis-to-bezier.h index b386bd520..07511f4a4 100644 --- a/src/2geom/sbasis-to-bezier.h +++ b/src/2geom/sbasis-to-bezier.h @@ -46,6 +46,7 @@ class PathBuilder; void sbasis_to_bezier (Bezier & bz, SBasis const& sb, size_t sz = 0); void sbasis_to_bezier (std::vector<Point> & bz, D2<SBasis> const& sb, size_t sz = 0); +void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb); void bezier_to_sbasis (SBasis & sb, Bezier const& bz); void bezier_to_sbasis (D2<SBasis> & sb, std::vector<Point> const& bz); void build_from_sbasis(PathBuilder &pb, D2<SBasis> const &B, double tol, bool only_cubicbeziers); diff --git a/src/2geom/solve-bezier-one-d.cpp b/src/2geom/solve-bezier-one-d.cpp index f14f701d0..3d87d4926 100644 --- a/src/2geom/solve-bezier-one-d.cpp +++ b/src/2geom/solve-bezier-one-d.cpp @@ -92,11 +92,10 @@ void Bernsteins::find_bernstein_roots(double const *w, /* The control points */ int old_sign = SGN(w[0]); //std::cout << "w[0] = " << w[0] << std::endl; - int sign; for (size_t i = 1; i < N; i++) { //std::cout << "w[" << i << "] = " << w[i] << std::endl; - sign = SGN(w[i]); + int sign = SGN(w[i]); if (sign != 0) { if (sign != old_sign && old_sign != 0) @@ -128,14 +127,14 @@ void Bernsteins::find_bernstein_roots(double const *w, /* The control points */ double s = 0, t = 1; double e = 1e-10; int side = 0; - double r, fr, fs = w[0], ft = w[degree]; + double r, fs = w[0], ft = w[degree]; for (size_t n = 0; n < 100; ++n) { r = (fs*t - ft*s) / (fs - ft); if (fabs(t-s) < e * fabs(t+s)) break; - fr = horner(w, r); + double fr = horner(w, r); if (fr * ft > 0) { diff --git a/src/2geom/solve-bezier-parametric.cpp b/src/2geom/solve-bezier-parametric.cpp index ed693c584..9b0feaee4 100644 --- a/src/2geom/solve-bezier-parametric.cpp +++ b/src/2geom/solve-bezier-parametric.cpp @@ -68,20 +68,16 @@ find_parametric_bezier_roots(Geom::Point const *w, /* The control points */ break; } - /* - * Otherwise, solve recursively after subdividing control polygon - * New left and right control polygons - */ - Geom::Point *Left = new Geom::Point[degree+1]; - Geom::Point *Right = new Geom::Point[degree+1]; - - Bezier(w, degree, 0.5, Left, Right); - total_subs ++; - find_parametric_bezier_roots(Left, degree, solutions, depth+1); - find_parametric_bezier_roots(Right, degree, solutions, depth+1); + /* Otherwise, solve recursively after subdividing control polygon */ + + //Geom::Point Left[degree+1], /* New left and right */ + // Right[degree+1]; /* control polygons */ + std::vector<Geom::Point> Left( degree+1 ), Right(degree+1); - delete[] Left; - delete[] Right; + Bezier(w, degree, 0.5, Left.data(), Right.data()); + total_subs ++; + find_parametric_bezier_roots(Left.data(), degree, solutions, depth+1); + find_parametric_bezier_roots(Right.data(), degree, solutions, depth+1); } @@ -130,7 +126,8 @@ control_poly_flat_enough(Geom::Point const *V, /* Control points */ const double abSquared = (a * a) + (b * b); - double distance[degree]; /* Distances from pts to line */ + //double distance[degree]; /* Distances from pts to line */ + std::vector<double> distance(degree); /* Distances from pts to line */ for (unsigned i = 1; i < degree; i++) { /* Compute distance from each of the points to that line */ double & dist(distance[i-1]); @@ -198,13 +195,13 @@ Bezier(Geom::Point const *V, /* Control pts */ Geom::Point *Left, /* RETURN left half ctl pts */ Geom::Point *Right) /* RETURN right half ctl pts */ { - Geom::Point **Vtemp = new Geom::Point* [degree+1]; - - for (unsigned int i = 0; i < degree+1; ++i) - Vtemp[i] = new Geom::Point[degree+1]; + //Geom::Point Vtemp[degree+1][degree+1]; + std::vector<std::vector<Geom::Point> > Vtemp(degree+1); + for ( size_t i = 0; i < degree + 1; ++i ) + Vtemp.reserve(degree+1); /* Copy control points */ - std::copy(V, V+degree+1, Vtemp[0]); + std::copy(V, V+degree+1, Vtemp[0].begin()); /* Triangle computation */ for (unsigned i = 1; i <= degree; i++) { @@ -218,14 +215,7 @@ Bezier(Geom::Point const *V, /* Control pts */ for (unsigned j = 0; j <= degree; j++) Right[j] = Vtemp[degree-j][j]; - Geom::Point return_value = Vtemp[degree][0]; - - for (unsigned int i = 0; i < degree+1; ++i) - delete[] Vtemp[i]; - - delete[] Vtemp; - - return return_value; + return (Vtemp[degree][0]); } }; diff --git a/src/2geom/solve-bezier.cpp b/src/2geom/solve-bezier.cpp index 09f8d9289..adf3c9ac0 100644 --- a/src/2geom/solve-bezier.cpp +++ b/src/2geom/solve-bezier.cpp @@ -80,7 +80,7 @@ void convex_hull_marching(Bezier src_bz, Bezier bz, double left_t, double right_t) { - while(bz.order() > 0 and bz[0] == 0) { + while(bz.order() > 0 && bz[0] == 0) { std::cout << "deflate\n"; bz = bz.deflate(); solutions.push_back(left_t); @@ -89,12 +89,11 @@ void convex_hull_marching(Bezier src_bz, Bezier bz, int old_sign = SGN(bz[0]); - int sign; double left_bound = 0; double dt = 0; for (size_t i = 1; i < bz.size(); i++) { - sign = SGN(bz[i]); + int sign = SGN(bz[i]); if (sign != old_sign) { dt = double(i) / bz.order(); @@ -113,7 +112,7 @@ void convex_hull_marching(Bezier src_bz, Bezier bz, double new_left_t = left_bound * (right_t - left_t) + left_t; std::cout << "new_left_t = " << new_left_t << std::endl; Bezier bzr = subRight(src_bz, new_left_t); - while(bzr.order() > 0 and bzr[0] == 0) { + while(bzr.order() > 0 && bzr[0] == 0) { std::cout << "deflate\n"; bzr = bzr.deflate(); solutions.push_back(new_left_t); @@ -124,7 +123,7 @@ void convex_hull_marching(Bezier src_bz, Bezier bz, new_left_t, right_t); } else { std::cout << "epsilon reached\n"; - while(bzr.order() > 0 and fabs(bzr[0]) <= 1e-10) { + while(bzr.order() > 0 && fabs(bzr[0]) <= 1e-10) { std::cout << "deflate\n"; bzr = bzr.deflate(); std::cout << bzr << std::endl; @@ -182,11 +181,10 @@ void Bernsteins::find_bernstein_roots(Bezier bz, int old_sign = SGN(bz[0]); //std::cout << "w[0] = " << bz[0] << std::endl; - int sign; for (size_t i = 1; i < bz.size(); i++) { //std::cout << "w[" << i << "] = " << w[i] << std::endl; - sign = SGN(bz[i]); + int sign = SGN(bz[i]); if (sign != 0) { if (sign != old_sign && old_sign != 0) @@ -259,7 +257,7 @@ void Bernsteins::find_bernstein_roots(Bezier bz, debug(std::cout << "Solution is exactly on the subdivision point.\n"); debug(std::cout << Left << " , " << Right << std::endl); Left = reverse(Left); - while(Right.order() > 0 and fabs(Right[0]) <= 1e-10) { + while(Right.order() > 0 && fabs(Right[0]) <= 1e-10) { debug(std::cout << "deflate\n"); Right = Right.deflate(); Left = Left.deflate(); @@ -293,7 +291,7 @@ double Bernsteins::secant(Bezier bz) { double s = 0, t = 1; double e = 1e-14; int side = 0; - double r, fr, fs = bz.at0(), ft = bz.at1(); + double r, fs = bz.at0(), ft = bz.at1(); for (size_t n = 0; n < 100; ++n) { @@ -305,7 +303,7 @@ double Bernsteins::secant(Bezier bz) { return r; } - fr = horner(bz, r); + double fr = horner(bz, r); if (fr * ft > 0) { diff --git a/src/2geom/svg-elliptical-arc.cpp b/src/2geom/svg-elliptical-arc.cpp index 14a4b4f16..96a4f99d8 100644 --- a/src/2geom/svg-elliptical-arc.cpp +++ b/src/2geom/svg-elliptical-arc.cpp @@ -218,15 +218,23 @@ bool make_elliptical_arc::make_elliptiarc() if (svg_compliant_flag()) { +#ifdef CPP11 + std::unique_ptr<EllipticalArc> arc( e.arc(initial_point, inner_point, final_point, true) ); +#else std::auto_ptr<EllipticalArc> arc( e.arc(initial_point, inner_point, final_point, true) ); +#endif ea = *arc; } else { try { - std::auto_ptr<EllipticalArc> eap( - e.arc(initial_point, inner_point, final_point, false) ); +#ifdef CPP11 + std::unique_ptr<EllipticalArc> +#else + std::auto_ptr<EllipticalArc> +#endif + eap( e.arc(initial_point, inner_point, final_point, false) ); ea = *eap; } catch(RangeError const &exc) diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index 60a734ece..fa31b57b5 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -1,4 +1,5 @@ -#line 1 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" + +#line 1 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" /** * \file * \brief parse SVG path specifications @@ -46,7 +47,7 @@ namespace { class Parser { public: - Parser(SVGPathSink &sink) : _absolute(false), _sink(sink) {} + Parser(PathSink &sink) : _absolute(false), _sink(sink) {} void parse(char const *str) throw(SVGPathParseError); @@ -57,7 +58,7 @@ private: Point _cubic_tangent; Point _quad_tangent; std::vector<double> _params; - SVGPathSink &_sink; + PathSink &_sink; void _reset() { _absolute = false; @@ -140,7 +141,7 @@ private: }; -#line 144 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp" +#line 145 "/home/tweenk/src/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, @@ -956,7 +957,7 @@ static const short _svg_path_indicies[] = { 1, 0 }; -static const short _svg_path_trans_targs_wi[] = { +static const short _svg_path_trans_targs[] = { 270, 0, 1, 2, 193, 3, 4, 5, 194, 3, 4, 5, 194, 5, 194, 6, 7, 8, 195, 9, 204, 7, 8, 195, @@ -1048,7 +1049,7 @@ static const short _svg_path_trans_targs_wi[] = { 268, 269 }; -static const char _svg_path_trans_actions_wi[] = { +static const char _svg_path_trans_actions[] = { 15, 0, 0, 0, 0, 9, 47, 47, 47, 0, 1, 1, 1, 0, 0, 0, 3, 17, 3, 17, 0, 0, 1, 0, @@ -1145,7 +1146,8 @@ static const int svg_path_first_final = 270; static const int svg_path_en_main = 1; -#line 144 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" + +#line 144 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" void Parser::parse(char const *str) @@ -1158,12 +1160,12 @@ throw(SVGPathParseError) _reset(); -#line 1162 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1164 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" { cs = svg_path_start; } -#line 1167 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1169 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" { int _klen; unsigned int _trans; @@ -1192,7 +1194,7 @@ _resume: else if ( (*p) > *_mid ) _lower = _mid + 1; else { - _trans += (_mid - _keys); + _trans += (unsigned int)(_mid - _keys); goto _match; } } @@ -1215,7 +1217,7 @@ _resume: else if ( (*p) > _mid[1] ) _lower = _mid + 2; else { - _trans += ((_mid - _keys)>>1); + _trans += (unsigned int)((_mid - _keys)>>1); goto _match; } } @@ -1224,25 +1226,25 @@ _resume: _match: _trans = _svg_path_indicies[_trans]; - cs = _svg_path_trans_targs_wi[_trans]; + cs = _svg_path_trans_targs[_trans]; - if ( _svg_path_trans_actions_wi[_trans] == 0 ) + if ( _svg_path_trans_actions[_trans] == 0 ) goto _again; - _acts = _svg_path_actions + _svg_path_trans_actions_wi[_trans]; + _acts = _svg_path_actions + _svg_path_trans_actions[_trans]; _nacts = (unsigned int) *_acts++; while ( _nacts-- > 0 ) { switch ( *_acts++ ) { case 0: -#line 156 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 156 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { start = p; } break; case 1: -#line 160 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 160 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { char const *end=p; std::string buf(start, end); @@ -1251,55 +1253,55 @@ _match: } break; case 2: -#line 167 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 167 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _push(1.0); } break; case 3: -#line 171 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 171 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _push(0.0); } break; case 4: -#line 175 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 175 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = true; } break; case 5: -#line 179 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 179 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = false; } break; case 6: -#line 183 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 183 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _moveTo(_pop_point()); } break; case 7: -#line 187 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 187 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _lineTo(_pop_point()); } break; case 8: -#line 191 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 191 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _hlineTo(Point(_pop_coord(X), _current[Y])); } break; case 9: -#line 195 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 195 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _vlineTo(Point(_current[X], _pop_coord(Y))); } break; case 10: -#line 199 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 199 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1308,7 +1310,7 @@ _match: } break; case 11: -#line 206 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 206 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1316,7 +1318,7 @@ _match: } break; case 12: -#line 212 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 212 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c = _pop_point(); @@ -1324,14 +1326,14 @@ _match: } break; case 13: -#line 218 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 218 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); _quadTo(_quad_tangent, p); } break; case 14: -#line 223 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 223 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point point = _pop_point(); bool sweep = _pop_flag(); @@ -1344,16 +1346,16 @@ _match: } break; case 15: -#line 234 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" +#line 234 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _closePath(); } break; case 16: -#line 370 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" - {goto _out;} +#line 370 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + {{p++; goto _out; }} break; -#line 1357 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.cpp" +#line 1359 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" } } @@ -1364,7 +1366,8 @@ _again: goto _resume; _out: {} } -#line 380 "/opt/shared/work/programming/eclipse/eclipse_3.4/lib2geom/src/2geom/svg-path-parser.rl" + +#line 380 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" if ( cs < svg_path_first_final ) { @@ -1374,12 +1377,12 @@ _again: } -void parse_svg_path(char const *str, SVGPathSink &sink) +void parse_svg_path(char const *str, PathSink &sink) throw(SVGPathParseError) { Parser parser(sink); parser.parse(str); - sink.finish(); + sink.flush(); } } @@ -1393,4 +1396,4 @@ throw(SVGPathParseError) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/2geom/svg-path-parser.h b/src/2geom/svg-path-parser.h index 365287d8c..163fbe5c4 100644 --- a/src/2geom/svg-path-parser.h +++ b/src/2geom/svg-path-parser.h @@ -38,11 +38,11 @@ #include <stdexcept> #include <2geom/exception.h> #include <2geom/point.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> namespace Geom { -void parse_svg_path(char const *str, SVGPathSink &sink) throw(SVGPathParseError); +void parse_svg_path(char const *str, PathSink &sink) throw(SVGPathParseError); inline std::vector<Path> parse_svg_path(char const *str) throw(SVGPathParseError) { typedef std::vector<Path> Subpaths; @@ -50,13 +50,14 @@ inline std::vector<Path> parse_svg_path(char const *str) throw(SVGPathParseError Subpaths subpaths; Inserter iter(subpaths); - SVGPathGenerator<Inserter> generator(iter); + PathIteratorSink<Inserter> generator(iter); parse_svg_path(str, generator); return subpaths; } inline std::vector<Path> read_svgd_f(FILE * fi) throw(SVGPathParseError) { + /// @bug The 10kB length limit should be removed char input[1024 * 10]; fgets(input, 1024 * 10, fi); return parse_svg_path(input); diff --git a/src/2geom/toposweep.h b/src/2geom/toposweep.h index 428115dd3..b6a55b154 100644 --- a/src/2geom/toposweep.h +++ b/src/2geom/toposweep.h @@ -193,7 +193,7 @@ Areas filter_areas(PathVector const &ps, Areas const & areas, Z const &z) { if(areas[i].size() < 2) continue; //find a representative section unsigned rj = 0; - bool rev = are_near(areas[i][0]->fp, areas[i][1]->tp); + //bool rev = are_near(areas[i][0]->fp, areas[i][1]->tp); for(unsigned j = 1; j < areas[i].size(); j++) if(sorty(*areas[i][rj], *areas[i][j])) rj = j; if(sortx(*areas[i][rj], *areas[i][(rj+areas[i].size() - 1) % areas[i].size()])) { diff --git a/src/2geom/transforms.cpp b/src/2geom/transforms.cpp index 65df9b22f..091079d5a 100644 --- a/src/2geom/transforms.cpp +++ b/src/2geom/transforms.cpp @@ -164,6 +164,7 @@ void check_transforms() // notice that the first column is always the same and enumerates all transform types, // while the second one changes to each transform type in turn. + // cppcheck-suppress redundantAssignment m = t * t; m = t * s; m = t * r; m = t * h; m = t * v; m = t * z; m = s * t; m = s * s; m = s * r; m = s * h; m = s * v; m = s * z; m = r * t; m = r * s; m = r * r; m = r * h; m = r * v; m = r * z; diff --git a/src/2geom/utils.cpp b/src/2geom/utils.cpp index a40b7253d..83d93cc87 100644 --- a/src/2geom/utils.cpp +++ b/src/2geom/utils.cpp @@ -37,16 +37,15 @@ namespace Geom { // return a vector that contains all the binomial coefficients of degree n -void binomial_coefficients(std::vector<size_t>& bc, size_t n) +void binomial_coefficients(std::vector<size_t>& bc, std::size_t n) { size_t s = n+1; bc.clear(); bc.resize(s); bc[0] = 1; - size_t k; for (size_t i = 1; i < n; ++i) { - k = i >> 1; + size_t k = i >> 1; if (i & 1u) { bc[k+1] = bc[k] << 1; diff --git a/src/2geom/utils.h b/src/2geom/utils.h index 6a72d42c4..fe955dd41 100644 --- a/src/2geom/utils.h +++ b/src/2geom/utils.h @@ -41,7 +41,7 @@ namespace Geom { // proper logical xor inline bool logical_xor (bool a, bool b) { return (a || b) && !(a && b); } -void binomial_coefficients(std::vector<size_t>& bc, size_t n); +void binomial_coefficients(std::vector<size_t>& bc, std::size_t n); struct EmptyClass {}; diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index e80f12486..03d7f51b5 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -12,7 +12,7 @@ #include <glib.h> #include <2geom/curves.h> #include <2geom/pathvector.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <2geom/svg-path-parser.h> #include "display/cairo-utils.h" diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 38a105459..434f3ee47 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -21,7 +21,7 @@ #include FT_TRUETYPE_TABLES_H #include <pango/pangoft2.h> #include <2geom/pathvector.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include "libnrtype/font-glyph.h" #include "libnrtype/font-instance.h" #include "livarot/Path.h" @@ -618,7 +618,7 @@ void font_instance::LoadGlyph(int glyph_id) doAdd=true; } #endif - path_builder.finish(); + path_builder.flush(); if ( doAdd ) { Geom::PathVector pv = path_builder.peek(); diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 0533c1ed6..acf8ab6a5 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -24,7 +24,7 @@ #include <2geom/bezier-utils.h> #include <2geom/svg-elliptical-arc.h> #include <2geom/sbasis-to-bezier.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <2geom/path-intersection.h> #include <2geom/crossing.h> #include <2geom/ellipse.h> @@ -537,7 +537,7 @@ static Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise<Geom::D2<Geom:: prev_i = i; } - pb.finish(); + pb.flush(); return pb.peek().front(); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 697b80608..25e4c07d7 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -29,7 +29,7 @@ #include <2geom/ellipse.h> #include <2geom/transforms.h> #include <2geom/pathvector.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include "document.h" #include "sp-ellipse.h" #include "preferences.h" @@ -441,7 +441,7 @@ void SPGenericEllipse::set_shape() pb.closePath(); } else { // arc only - pb.finish(); + pb.flush(); } curve = new SPCurve(pb.peek()); diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp index 135f9ff75..59dad9ead 100644 --- a/src/svg/svg-path.cpp +++ b/src/svg/svg-path.cpp @@ -40,7 +40,7 @@ #include <2geom/path.h> #include <2geom/curves.h> #include <2geom/sbasis-to-bezier.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <2geom/svg-path-parser.h> #include <2geom/exception.h> #include <2geom/angle.h> @@ -59,13 +59,13 @@ Geom::PathVector sp_svg_read_pathv(char const * str) typedef std::back_insert_iterator<Geom::PathVector> Inserter; Inserter iter(pathv); - Geom::SVGPathGenerator<Inserter> generator(iter); + Geom::PathIteratorSink<Inserter> generator(iter); try { Geom::parse_svg_path(str, generator); } catch (Geom::SVGPathParseError &e) { - generator.finish(); + generator.flush(); // This warning is extremely annoying when testing //g_warning("Malformed SVG path, truncated path up to where error was found.\n Input path=\"%s\"\n Parsed path=\"%s\"", str, sp_svg_write_path(pathv)); } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index ec58e2141..338499672 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -18,7 +18,7 @@ #include <boost/shared_ptr.hpp> #include <2geom/bezier-curve.h> #include <2geom/bezier-utils.h> -#include <2geom/svg-path.h> +#include <2geom/path-sink.h> #include <glibmm/i18n.h> #include "ui/tool/path-manipulator.h" #include "desktop.h" @@ -1202,7 +1202,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } ++spi; } - builder.finish(); + builder.flush(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); if (alert_LPE) { |
