22
22
#include <libnr/nr-i-coord.h>
23
23
#include <libnr/nr-dim2.h>
24
24
#include <libnr/nr-point.h>
25
#include <libnr/nr-maybe.h>
25
#include <boost/optional.hpp>
26
26
#include <libnr/nr-point-matrix-ops.h>
27
#include <libnr/nr-forward.h>
28
#include <2geom/rect.h>
31
32
/** A rectangle is always aligned to the X and Y axis. This means it
32
33
* can be defined using only 4 coordinates, and determining
147
148
friend inline std::ostream &operator<<(std::ostream &out_file, NR::Rect const &in_rect);
150
Rect(Nothing) : _min(1, 1), _max(-1, -1) {}
151
// Rect(Nothing) : _min(1, 1), _max(-1, -1) {}
152
153
static double _inf() {
153
154
return std::numeric_limits<double>::infinity();
181
182
Point _min, _max;
183
friend class MaybeStorage<Rect>;
184
friend Maybe<Rect> intersection(Maybe<Rect> const &, Maybe<Rect> const &);
184
friend boost::optional<Rect> intersection(boost::optional<Rect> const &, boost::optional<Rect> const &);
185
185
friend Rect union_bounds(Rect const &, Rect const &);
189
class MaybeStorage<Rect> {
191
MaybeStorage() : _rect(Nothing()) {}
192
MaybeStorage(Rect const &rect) : _rect(rect) {}
194
bool is_nothing() const {
195
return _rect._min[X] > _rect._max[X];
197
Rect const &value() const { return _rect; }
198
Rect &value() { return _rect; }
204
188
/** Returns the set of points shared by both rectangles. */
205
Maybe<Rect> intersection(Maybe<Rect> const & a, Maybe<Rect> const & b);
189
boost::optional<Rect> intersection(boost::optional<Rect> const & a, boost::optional<Rect> const & b);
207
191
/** Returns the smallest rectangle that encloses both rectangles. */
208
192
Rect union_bounds(Rect const &a, Rect const &b);
209
inline Rect union_bounds(Maybe<Rect> const & a, Rect const &b) {
193
inline Rect union_bounds(boost::optional<Rect> const & a, Rect const &b) {
211
195
return union_bounds(*a, b);
216
inline Rect union_bounds(Rect const &a, Maybe<Rect> const & b) {
200
inline Rect union_bounds(Rect const &a, boost::optional<Rect> const & b) {
218
202
return union_bounds(a, *b);
223
inline Maybe<Rect> union_bounds(Maybe<Rect> const & a, Maybe<Rect> const & b)
207
inline boost::optional<Rect> union_bounds(boost::optional<Rect> const & a, boost::optional<Rect> const & b)
248
232
/* legacy rect stuff */
252
234
/* NULL rect is infinite */
238
: x0(0), y0(0), x1(0), y1(0)
256
240
NRRect(NR::Coord xmin, NR::Coord ymin, NR::Coord xmax, NR::Coord ymax)
257
241
: x0(xmin), y0(ymin), x1(xmax), y1(ymax)
259
243
explicit NRRect(NR::Rect const &rect);
260
explicit NRRect(NR::Maybe<NR::Rect> const &rect);
261
operator NR::Maybe<NR::Rect>() const { return upgrade(); }
262
NR::Maybe<NR::Rect> upgrade() const;
244
explicit NRRect(boost::optional<NR::Rect> const &rect);
245
operator boost::optional<NR::Rect>() const { return upgrade(); }
246
boost::optional<NR::Rect> upgrade() const;
247
explicit NRRect(Geom::OptRect const &rect);
248
operator Geom::OptRect() const { return upgrade_2geom(); }
249
Geom::OptRect upgrade_2geom() const;
264
251
NR::Coord x0, y0, x1, y1;
268
255
#define nr_rect_l_set_empty(r) (*(r) = NR_RECT_L_EMPTY)
270
257
/** "Empty" here includes the case of zero width or zero height. */
271
#define nr_rect_d_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r))
272
#define nr_rect_l_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r))
258
// TODO convert to static overloaded functions (pointer and ref) once performance can be tested:
259
#define nr_rect_d_test_empty_ptr(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r))
260
#define nr_rect_d_test_empty(r) NR_RECT_DFLS_TEST_EMPTY_REF(r)
262
// TODO convert to static overloaded functions (pointer and ref) once performance can be tested:
263
#define nr_rect_l_test_empty_ptr(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r))
264
#define nr_rect_l_test_empty(r) NR_RECT_DFLS_TEST_EMPTY_REF(r)
274
266
#define nr_rect_d_test_intersect(r0,r1) \
275
267
(!nr_rect_d_test_empty(r0) && !nr_rect_d_test_empty(r1) && \
276
268
!((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1)))
270
// TODO convert to static overloaded functions (pointer and ref) once performance can be tested:
271
#define nr_rect_l_test_intersect_ptr(r0,r1) \
272
(!nr_rect_l_test_empty_ptr(r0) && !nr_rect_l_test_empty_ptr(r1) && \
273
!((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1)))
277
274
#define nr_rect_l_test_intersect(r0,r1) \
278
275
(!nr_rect_l_test_empty(r0) && !nr_rect_l_test_empty(r1) && \
279
!((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1)))
276
!(!NR_RECT_DFLS_TEST_INTERSECT_REF(r0, r1)))
281
278
#define nr_rect_d_point_d_test_inside(r,p) ((p) && (!(r) || (!NR_RECT_DF_TEST_EMPTY(r) && NR_RECT_DF_POINT_DF_TEST_INSIDE(r,p))))
282
279
#define nr_rect_l_point_l_test_inside(r,p) ((p) && (!(r) || (!NR_RECT_DFLS_TEST_EMPTY(r) && NR_RECT_LS_POINT_LS_TEST_INSIDE(r,p))))
300
297
NRRectL *nr_rect_l_union_xy(NRRectL *d, NR::ICoord x, NR::ICoord y);
302
299
NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NR::Matrix const &m);
303
NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NRMatrix const *m);
300
NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NR::Matrix const *m);
304
301
NRRectL *nr_rect_l_enlarge(NRRectL *d, int amount);