summaryrefslogtreecommitdiffstats
path: root/src/2geom
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-07-22 02:09:27 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-07-22 02:09:27 +0000
commit328fad57dbfb65e3bd31062021d5cc3081e68515 (patch)
tree55b02cfb325a87d994fefb0e4ea88311812e9444 /src/2geom
parentClean up some commented-out code (diff)
downloadinkscape-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.h4
-rw-r--r--src/2geom/bezier-curve.cpp5
-rw-r--r--src/2geom/coord.h6
-rw-r--r--src/2geom/forward.h1
-rw-r--r--src/2geom/generic-interval.h4
-rw-r--r--src/2geom/generic-rect.h26
-rw-r--r--src/2geom/int-point.h5
-rw-r--r--src/2geom/interval.h15
-rw-r--r--src/2geom/path-intersection.cpp2
-rw-r--r--src/2geom/point.h15
-rw-r--r--src/2geom/rect.h30
-rw-r--r--src/2geom/transforms.h85
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