1 #ifndef SEEN_NR_RECT_L_H
2 #define SEEN_NR_RECT_L_H
4 #include <libnr/nr-i-coord.h>
5 #include <libnr/nr-maybe.h>
6 #include <libnr/nr-rect.h>
7 #include <libnr/nr-point-l.h>
9 struct NRRectL {
10 NR::Maybe<NR::Rect> upgrade() const;
11 NR::ICoord x0, y0, x1, y1;
12 };
15 namespace NR {
18 class IRect {
19 public:
20 IRect(const NRRectL& r) : _min(r.x0, r.y0), _max(r.x1, r.y1) {}
21 IRect(const IRect& r) : _min(r._min), _max(r._max) {}
22 IRect(const IPoint &p0, const IPoint &p1);
24 /** as not all Rects are representable by IRects this gives the smallest IRect that contains
25 * r. */
26 IRect(const Rect& r);
28 operator Rect() {
29 return Rect(Point(_min), Point(_max));
30 }
32 const IPoint &min() const { return _min; }
33 const IPoint &max() const { return _max; }
35 /** returns a vector from min to max. */
36 IPoint dimensions() const;
38 /** does this rectangle have zero area? */
39 bool isEmpty() const {
40 return isEmpty<X>() && isEmpty<Y>();
41 }
43 bool intersects(const IRect &r) const {
44 return intersects<X>(r) && intersects<Y>(r);
45 }
46 bool contains(const IRect &r) const {
47 return contains<X>(r) && contains<Y>(r);
48 }
49 bool contains(const IPoint &p) const {
50 return contains<X>(p) && contains<Y>(p);
51 }
53 ICoord maxExtent() const {
54 return MAX(extent<X>(), extent<Y>());
55 }
57 ICoord extent(Dim2 axis) const {
58 switch (axis) {
59 case X: return extent<X>();
60 case Y: return extent<Y>();
61 };
62 }
64 ICoord extent(unsigned i) const throw(std::out_of_range) {
65 switch (i) {
66 case 0: return extent<X>();
67 case 1: return extent<Y>();
68 default: throw std::out_of_range("Dimension out of range");
69 };
70 }
72 /** Translates the rectangle by p. */
73 void offset(IPoint p);
75 /** Makes this rectangle large enough to include the point p. */
76 void expandTo(IPoint p);
78 /** Makes this rectangle large enough to include the rectangle r. */
79 void expandTo(const IRect &r);
81 /** Returns the set of points shared by both rectangles. */
82 static Maybe<IRect> intersection(const IRect &a, const IRect &b);
84 /** Returns the smallest rectangle that encloses both rectangles. */
85 static IRect union_bounds(const IRect &a, const IRect &b);
87 private:
88 IRect() {}
90 template <NR::Dim2 axis>
91 ICoord extent() const {
92 return _max[axis] - _min[axis];
93 }
95 template <Dim2 axis>
96 bool isEmpty() const {
97 return !( _min[axis] < _max[axis] );
98 }
100 template <Dim2 axis>
101 bool intersects(const IRect &r) const {
102 return _max[axis] >= r._min[axis] && _min[axis] <= r._max[axis];
103 }
105 template <Dim2 axis>
106 bool contains(const IRect &r) const {
107 return contains(r._min) && contains(r._max);
108 }
110 template <Dim2 axis>
111 bool contains(const IPoint &p) const {
112 return p[axis] >= _min[axis] && p[axis] <= _max[axis];
113 }
115 IPoint _min, _max;
116 };
120 } // namespace NR
122 #endif /* !SEEN_NR_RECT_L_H */
124 /*
125 Local Variables:
126 mode:c++
127 c-file-style:"stroustrup"
128 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
129 indent-tabs-mode:nil
130 fill-column:99
131 End:
132 */
133 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :