diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-07-22 02:09:27 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-07-22 02:09:27 +0000 |
| commit | 328fad57dbfb65e3bd31062021d5cc3081e68515 (patch) | |
| tree | 55b02cfb325a87d994fefb0e4ea88311812e9444 /src/2geom | |
| parent | Clean up some commented-out code (diff) | |
| download | inkscape-328fad57dbfb65e3bd31062021d5cc3081e68515.tar.gz inkscape-328fad57dbfb65e3bd31062021d5cc3081e68515.zip | |
Replace direct use of Cairo contexts and surfaces in the rendering tree
with wrappers which keep some extra information about the surface,
amd NRRect and NRRectL use with Geom::Rect and Geom::IntRect.
Should simplify implementing filter primitive subregions.
(bzr r10347.1.17)
Diffstat (limited to 'src/2geom')
| -rw-r--r-- | src/2geom/affine.h | 4 | ||||
| -rw-r--r-- | src/2geom/bezier-curve.cpp | 5 | ||||
| -rw-r--r-- | src/2geom/coord.h | 6 | ||||
| -rw-r--r-- | src/2geom/forward.h | 1 | ||||
| -rw-r--r-- | src/2geom/generic-interval.h | 4 | ||||
| -rw-r--r-- | src/2geom/generic-rect.h | 26 | ||||
| -rw-r--r-- | src/2geom/int-point.h | 5 | ||||
| -rw-r--r-- | src/2geom/interval.h | 15 | ||||
| -rw-r--r-- | src/2geom/path-intersection.cpp | 2 | ||||
| -rw-r--r-- | src/2geom/point.h | 15 | ||||
| -rw-r--r-- | src/2geom/rect.h | 30 | ||||
| -rw-r--r-- | src/2geom/transforms.h | 85 |
12 files changed, 129 insertions, 69 deletions
diff --git a/src/2geom/affine.h b/src/2geom/affine.h index b07fba0f7..d7a7a0692 100644 --- a/src/2geom/affine.h +++ b/src/2geom/affine.h @@ -65,7 +65,8 @@ class Affine , MultipliableNoncommutative< Affine, Rotate , MultipliableNoncommutative< Affine, HShear , MultipliableNoncommutative< Affine, VShear - > > > > > > > + , MultipliableNoncommutative< Affine, Zoom + > > > > > > > > { Coord _c[6]; public: @@ -113,6 +114,7 @@ public: Affine &operator*=(Rotate const &r); Affine &operator*=(HShear const &h); Affine &operator*=(VShear const &v); + Affine &operator*=(Zoom const &); /// @} bool operator==(Affine const &o) const { diff --git a/src/2geom/bezier-curve.cpp b/src/2geom/bezier-curve.cpp index 46aff8b49..8c40e5e42 100644 --- a/src/2geom/bezier-curve.cpp +++ b/src/2geom/bezier-curve.cpp @@ -106,10 +106,11 @@ namespace Geom BezierCurve::BezierCurve(std::vector<Point> const &pts) { - inner = D2<Bezier>(Bezier::Order(pts.size()-1), Bezier::Order(pts.size()-1)); + inner = D2<Bezier>(Bezier::Order(pts.size() - 1), Bezier::Order(pts.size() - 1)); for (unsigned d = 0; d < 2; ++d) { - for(unsigned i = 0; i <= pts.size(); i++) + for(unsigned i = 0; i < pts.size(); i++) { inner[d][i] = pts[i][d]; + } } } diff --git a/src/2geom/coord.h b/src/2geom/coord.h index c7bbcdcd4..f7bf2c5d0 100644 --- a/src/2geom/coord.h +++ b/src/2geom/coord.h @@ -69,9 +69,6 @@ struct CoordTraits<IntCoord> { typedef OptIntInterval OptIntervalType; typedef IntRect RectType; typedef OptIntRect OptRectType; - inline static bool contains(IntCoord low, IntCoord high, IntCoord testlow, IntCoord testhigh) { - return low <= testlow && testhigh < high; - } }; template<> @@ -81,9 +78,6 @@ struct CoordTraits<Coord> { typedef OptInterval OptIntervalType; typedef Rect RectType; typedef OptRect OptRectType; - inline static bool contains(Coord low, Coord high, Coord testlow, Coord testhigh) { - return low <= testlow && testhigh <= high; - } }; } // end namespace Geom diff --git a/src/2geom/forward.h b/src/2geom/forward.h index b1cad6f1f..0dbd9fa94 100644 --- a/src/2geom/forward.h +++ b/src/2geom/forward.h @@ -97,6 +97,7 @@ class Rotate; class Scale; class HShear; class VShear; +class Zoom; // templates template <typename> class D2; diff --git a/src/2geom/generic-interval.h b/src/2geom/generic-interval.h index d719c16c8..a32e97d4b 100644 --- a/src/2geom/generic-interval.h +++ b/src/2geom/generic-interval.h @@ -106,11 +106,11 @@ public: /// @{ /** @brief Check whether the interval includes this number. */ bool contains(C val) const { - return CoordTraits<C>::contains(min(), max(), val, val); + return min() <= val && val <= max(); } /** @brief Check whether the interval includes the given interval. */ bool contains(Self const &val) const { - return CoordTraits<C>::contains(min(), max(), val.min(), val.max()); + return min() <= val.min() && val.max() <= max(); } /** @brief Check whether the intervals have any common elements. */ bool intersects(Self const &val) const { diff --git a/src/2geom/generic-rect.h b/src/2geom/generic-rect.h index d60c4bb0f..6dc57b169 100644 --- a/src/2geom/generic-rect.h +++ b/src/2geom/generic-rect.h @@ -40,6 +40,7 @@ #ifndef LIB2GEOM_SEEN_GENERIC_RECT_H #define LIB2GEOM_SEEN_GENERIC_RECT_H +#include <limits> #include <boost/optional.hpp> namespace Geom { @@ -93,30 +94,37 @@ public: * @param end End of the range * @return Rectangle that contains all points from [start, end). */ template <typename InputIterator> - static GenericRect<C> from_range(InputIterator start, InputIterator end) { + static CRect from_range(InputIterator start, InputIterator end) { assert(start != end); CPoint p1 = *start++; - GenericRect<C> result(p1, p1); + CRect result(p1, p1); for (; start != end; ++start) { result.expandTo(*start); } return result; } /** @brief Create a rectangle from a C-style array of points it should contain. */ - static GenericRect<C> from_array(CPoint const *c, unsigned n) { - GenericRect<C> result = GenericRect<C>::from_range(c, c+n); + static CRect from_array(CPoint const *c, unsigned n) { + CRect result = GenericRect<C>::from_range(c, c+n); return result; } /** @brief Create rectangle from origin and dimensions. */ - static GenericRect<C> from_xywh(C x, C y, C w, C h) { + static CRect from_xywh(C x, C y, C w, C h) { CPoint xy(x, y); CPoint wh(w, h); - GenericRect<C> result(xy, xy + wh); + CRect result(xy, xy + wh); return result; } /** @brief Create rectangle from origin and dimensions. */ - static GenericRect<C> from_xywh(CPoint const &xy, CPoint const &wh) { - GenericRect<C> result(xy, xy + wh); + static CRect from_xywh(CPoint const &xy, CPoint const &wh) { + CRect result(xy, xy + wh); + return result; + } + /// Create infinite rectangle. + static CRect infinite() { + CPoint p0(std::numeric_limits<C>::min(), std::numeric_limits<C>::min()); + CPoint p1(std::numeric_limits<C>::max(), std::numeric_limits<C>::max()); + CRect result(p0, p1); return result; } /// @} @@ -155,6 +163,8 @@ public: C width() const { return f[X].extent(); } /** @brief Get the vertical extent of the rectangle. */ C height() const { return f[Y].extent(); } + /** @brief Get the ratio of width to height of the rectangle. */ + Coord aspectRatio() const { return Coord(width()) / Coord(height()); } /** @brief Get rectangle's width and height as a point. * @return Point with X coordinate corresponding to the width and the Y coordinate diff --git a/src/2geom/int-point.h b/src/2geom/int-point.h index cf2fe720f..1a16ecb7a 100644 --- a/src/2geom/int-point.h +++ b/src/2geom/int-point.h @@ -83,6 +83,11 @@ public: } IntCoord operator[](Dim2 d) const { return _pt[d]; } IntCoord &operator[](Dim2 d) { return _pt[d]; } + + IntCoord x() const throw() { return _pt[X]; } + IntCoord &x() throw() { return _pt[X]; } + IntCoord y() const throw() { return _pt[Y]; } + IntCoord &y() throw() { return _pt[Y]; } /// @} /// @name Vector-like arithmetic operations diff --git a/src/2geom/interval.h b/src/2geom/interval.h index ee6d674d2..e95da4811 100644 --- a/src/2geom/interval.h +++ b/src/2geom/interval.h @@ -64,7 +64,7 @@ typedef GenericOptInterval<Coord> OptInterval; class Interval : public GenericInterval<Coord> , boost::multipliable< Interval - , boost::multipliable< Interval, Coord + , boost::multiplicative< Interval, Coord > > { typedef GenericInterval<Coord> Base; @@ -180,7 +180,20 @@ public: /// @} }; +// functions required for Python bindings +inline Interval unify(Interval const &a, Interval const &b) +{ + Interval r = a | b; + return r; +} +inline OptInterval intersect(Interval const &a, Interval const &b) +{ + OptInterval r = a & b; + return r; } + +} // end namespace Geom + #endif //SEEN_INTERVAL_H /* diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index 7aa662abb..be3e3b7cc 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -271,6 +271,8 @@ intersect_polish_root (Curve const &A, double &s, } #ifdef HAVE_GSL + int status; + size_t iter = 0; if(0) { // the GSL version is more accurate, but taints this with GPL const size_t n = 2; struct rparams p = {A, B}; diff --git a/src/2geom/point.h b/src/2geom/point.h index 69da8a4ae..0eb771874 100644 --- a/src/2geom/point.h +++ b/src/2geom/point.h @@ -58,7 +58,8 @@ class Point , MultipliableNoncommutative< Point, Scale , MultipliableNoncommutative< Point, HShear , MultipliableNoncommutative< Point, VShear - > > > > > > > > > // this uses chaining so it looks weird, but works + , MultipliableNoncommutative< Point, Zoom + > > > > > > > > > > // this uses chaining so it looks weird, but works { Coord _pt[2]; public: @@ -111,6 +112,11 @@ public: Coord operator[](Dim2 d) const throw() { return _pt[d]; } Coord &operator[](Dim2 d) throw() { return _pt[d]; } + + Coord x() const throw() { return _pt[X]; } + Coord &x() throw() { return _pt[X]; } + Coord y() const throw() { return _pt[Y]; } + Coord &y() throw() { return _pt[Y]; } /// @} /// @name Vector operations @@ -172,12 +178,7 @@ public: Point &operator*=(Rotate const &r); Point &operator*=(HShear const &s); Point &operator*=(VShear const &s); - /** @brief Transform the point by the inverse of the specified matrix. */ - template <typename T> - Point &operator/=(T const &m) { - *this *= m.inverse(); - return *this; - } + Point &operator*=(Zoom const &z); /// @} /// @name Conversion to integer points diff --git a/src/2geom/rect.h b/src/2geom/rect.h index e9f6cbeb7..f7d331523 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -73,31 +73,7 @@ public: Rect(Point const &a, Point const &b) : Base(a,b) {} Rect(Coord x0, Coord y0, Coord x1, Coord y1) : Base(x0, y0, x1, y1) {} Rect(Base const &b) : Base(b) {} - /** @brief Create a rectangle from a range of points. - * The resulting rectangle will contain all ponts from the range. - * The return type of iterators must be convertible to Point. - * The range must not be empty. For possibly empty ranges, see OptRect. - * @param start Beginning of the range - * @param end End of the range - * @return Rectangle that contains all points from [start, end). */ - template <typename InputIterator> - static Rect from_range(InputIterator start, InputIterator end) { - Rect result = Base::from_range(start, end); - return result; - } - /** @brief Create a rectangle from a C-style array of points it should contain. */ - static Rect from_array(Point const *c, unsigned n) { - Rect result = Rect::from_range(c, c+n); - return result; - } - static Rect from_xywh(Coord x, Coord y, Coord w, Coord h) { - Rect result = Base::from_xywh(x, y, w, h); - return result; - } - static Rect from_xywh(Point const &o, Point const &dim) { - Rect result = Base::from_xywh(o, dim); - return result; - } + Rect(IntRect const &ir) : Base(ir.min(), ir.max()) {} /// @} /// @name Inspect dimensions. @@ -114,6 +90,10 @@ public: bool interiorIntersects(Rect const &r) const { return f[X].interiorIntersects(r[X]) && f[Y].interiorIntersects(r[Y]); } + /** @brief Check whether the interior includes the given point. */ + bool interiorContains(Point const &p) const { + return f[X].interiorContains(p[X]) && f[Y].interiorContains(p[Y]); + } /** @brief Check whether the interior includes all points in the given rectangle. * Interior of the rectangle is the entire rectangle without its borders. */ bool interiorContains(Rect const &r) const { diff --git a/src/2geom/transforms.h b/src/2geom/transforms.h index 9623bed26..5627e8b6f 100644 --- a/src/2geom/transforms.h +++ b/src/2geom/transforms.h @@ -106,13 +106,14 @@ T pow(T const &t, int n) { class Translate : public TransformOperations< Translate > { - Translate() : vec(0, 0) {} Point vec; public: - /** @brief Construct a translation from its vector. */ - explicit Translate(Point const &p) : vec(p) {} - /** @brief Construct a translation from its coordinates. */ - explicit Translate(Coord x, Coord y) : vec(x, y) {} + /// Create a translation that doesn't do anything. + Translate() : vec(0, 0) {} + /// Construct a translation from its vector. + Translate(Point const &p) : vec(p) {} + /// Construct a translation from its coordinates. + Translate(Coord x, Coord y) : vec(x, y) {} operator Affine() const { Affine ret(1, 0, 0, 1, vec[X], vec[Y]); return ret; } Coord operator[](Dim2 dim) const { return vec[dim]; } @@ -120,9 +121,10 @@ public: Translate &operator*=(Translate const &o) { vec += o.vec; return *this; } bool operator==(Translate const &o) const { return vec == o.vec; } - /** @brief Get the inverse translation. */ + Point vector() const { return vec; } + /// Get the inverse translation. Translate inverse() const { return Translate(-vec); } - /** @brief Get a translation that doesn't do anything. */ + /// Get a translation that doesn't do anything. static Translate identity() { Translate ret; return ret; } friend class Point; @@ -136,10 +138,14 @@ class Scale : public TransformOperations< Scale > { Point vec; - Scale() : vec(1, 1) {} public: + /// Create a scaling that doesn't do anything. + Scale() : vec(1, 1) {} + /// Create a scaling from two scaling factors given as coordinates of a point. explicit Scale(Point const &p) : vec(p) {} + /// Create a scaling from two scaling factors. Scale(Coord x, Coord y) : vec(x, y) {} + /// Create an uniform scaling from a single scaling factor. explicit Scale(Coord s) : vec(s, s) {} inline operator Affine() const { Affine ret(vec[X], 0, 0, vec[Y], 0, 0); return ret; } @@ -150,6 +156,8 @@ public: Coord &operator[](unsigned d) { return vec[d]; } Scale &operator*=(Scale const &b) { vec[X] *= b[X]; vec[Y] *= b[Y]; return *this; } bool operator==(Scale const &o) const { return vec == o.vec; } + + Point vector() const { return vec; } Scale inverse() const { return Scale(1./vec[0], 1./vec[1]); } static Scale identity() { Scale ret; return ret; } @@ -162,15 +170,16 @@ public: class Rotate : public TransformOperations< Rotate > { - Rotate() : vec(1, 0) {} - Point vec; + Point vec; ///< @todo Convert to storing the angle, as it's more space-efficient. public: + /// Construct a zero-degree rotation. + Rotate() : vec(1, 0) {} /** @brief Construct a rotation from its angle in radians. * Positive arguments correspond to counter-clockwise rotations (if Y grows upwards). */ explicit Rotate(Coord theta) : vec(Point::polar(theta)) {} - /** @brief Construct a rotation from its characteristic vector. */ + /// Construct a rotation from its characteristic vector. explicit Rotate(Point const &p) : vec(unit_vector(p)) {} - /** @brief Construct a rotation from the coordinates of its characteristic vector. */ + /// Construct a rotation from the coordinates of its characteristic vector. explicit Rotate(Coord x, Coord y) { Rotate(Point(x, y)); } operator Affine() const { Affine ret(vec[X], vec[Y], -vec[Y], vec[X], 0, 0); return ret; } @@ -186,10 +195,10 @@ public: r.vec = Point(vec[X], -vec[Y]); return r; } - /** @brief Get a 0-degree rotation. */ + /// @brief Get a zero-degree rotation. static Rotate identity() { Rotate ret; return ret; } /** @brief Construct a rotation from its angle in degrees. - * Positive arguments correspond to counter-clockwise rotations (if Y grows upwards). */ + * Positive arguments correspond to clockwise rotations if Y grows downwards. */ static Rotate from_degrees(Coord deg) { Coord rad = (deg / 180.0) * M_PI; return Rotate(rad); @@ -213,8 +222,8 @@ public: void setFactor(Coord nf) { f = nf; } S &operator*=(S const &s) { f += s.f; return static_cast<S &>(*this); } bool operator==(S const &s) const { return f == s.f; } - S inverse() const { return S(-f); } - static S identity() { return S(0); } + S inverse() const { S ret(-f); return ret; } + static S identity() { S ret(0); return ret; } friend class Point; friend class Affine; @@ -244,6 +253,48 @@ public: operator Affine() const { Affine ret(1, f, 0, 1, 0, 0); return ret; } }; +/** @brief Combination of a translation and uniform scale. + * The translation part is applied first, then the result is scaled from the new origin. + * This way when the class is used to accumulate a zoom transform, trans always points + * to the new origin in original coordinates. + * @ingroup Transform */ +class Zoom + : public TransformOperations< Zoom > +{ + Coord _scale; + Point _trans; + Zoom() : _scale(1), _trans() {} +public: + /// Construct a zoom from a scaling factor. + explicit Zoom(Coord s) : _scale(s), _trans() {} + /// Construct a zoom from a translation. + explicit Zoom(Translate const &t) : _scale(1), _trans(t.vector()) {} + /// Construct a zoom from a scaling factor and a translation. + Zoom(Coord s, Translate const &t) : _scale(s), _trans(t.vector()) {} + + operator Affine() const { + Affine ret(_scale, 0, 0, _scale, _trans[X] * _scale, _trans[Y] * _scale); + return ret; + } + Zoom &operator*=(Zoom const &z) { + _trans += z._trans / _scale; + _scale *= z._scale; + return *this; + } + bool operator==(Zoom const &z) const { return _scale == z._scale && _trans == z._trans; } + + Coord scale() const { return _scale; } + void setScale(Coord s) { _scale = s; } + Point translation() const { return _trans; } + void setTranslation(Point const &p) { _trans = p; } + Zoom inverse() const { Zoom ret(1/_scale, Translate(-_trans*_scale)); return ret; } + static Zoom identity() { Zoom ret(1.0); return ret; } + static Zoom map_rect(Rect const &old_r, Rect const &new_r); + + friend class Point; + friend class Affine; +}; + /** @brief Specialization of exponentiation for Scale. * @relates Scale */ template<> @@ -259,7 +310,7 @@ inline Translate pow(Translate const &t, int n) { return ret; } -//TODO: matrix to trans/scale/rotate +//TODO: decomposition of Affine into some finite combination of the above classes } // end namespace Geom |
