X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flibnr%2Fnr-rect.h;h=c074b00347c34160ea1bee9e6da0bb5f25128c7e;hb=62dad53172661dfa1ef8dd3ed07e06d2ea2523a4;hp=04f446487cccbb3928ded725fc143ecf8cbc2a70;hpb=d0ec2cc4f82877b76697e2fc7aa21b73d61c63d0;p=inkscape.git diff --git a/src/libnr/nr-rect.h b/src/libnr/nr-rect.h index 04f446487..c074b0034 100644 --- a/src/libnr/nr-rect.h +++ b/src/libnr/nr-rect.h @@ -22,11 +22,12 @@ #include #include #include -#include +#include #include +#include +#include <2geom/rect.h> namespace NR { - struct Matrix; /** A rectangle is always aligned to the X and Y axis. This means it * can be defined using only 4 coordinates, and determining @@ -53,6 +54,9 @@ public: /** returns the midpoint of this rect. */ Point midpoint() const; + Point cornerFarthestFrom(Point const &p) const; + + /** True iff either width or height is less than \a epsilon. */ bool isEmpty(double epsilon=1e-6) const { return isEmpty(epsilon) || isEmpty(epsilon); } @@ -144,7 +148,7 @@ public: friend inline std::ostream &operator<<(std::ostream &out_file, NR::Rect const &in_rect); private: - Rect(Nothing) : _min(1, 1), _max(-1, -1) {} +// Rect(Nothing) : _min(1, 1), _max(-1, -1) {} static double _inf() { return std::numeric_limits::infinity(); @@ -177,47 +181,30 @@ private: Point _min, _max; - friend class MaybeStorage; - friend Maybe intersection(Maybe const &, Maybe const &); + friend boost::optional intersection(boost::optional const &, boost::optional const &); friend Rect union_bounds(Rect const &, Rect const &); }; -template <> -class MaybeStorage { -public: - MaybeStorage() : _rect(Nothing()) {} - MaybeStorage(Rect const &rect) : _rect(rect) {} - - bool is_nothing() const { - return _rect._min[X] > _rect._max[X]; - } - Rect const &value() const { return _rect; } - Rect &value() { return _rect; } - -private: - Rect _rect; -}; - /** Returns the set of points shared by both rectangles. */ -Maybe intersection(Maybe const & a, Maybe const & b); +boost::optional intersection(boost::optional const & a, boost::optional const & b); /** Returns the smallest rectangle that encloses both rectangles. */ Rect union_bounds(Rect const &a, Rect const &b); -inline Rect union_bounds(Maybe const & a, Rect const &b) { +inline Rect union_bounds(boost::optional const & a, Rect const &b) { if (a) { return union_bounds(*a, b); } else { return b; } } -inline Rect union_bounds(Rect const &a, Maybe const & b) { +inline Rect union_bounds(Rect const &a, boost::optional const & b) { if (b) { return union_bounds(a, *b); } else { return a; } } -inline Maybe union_bounds(Maybe const & a, Maybe const & b) +inline boost::optional union_bounds(boost::optional const & a, boost::optional const & b) { if (!a) { return b; @@ -244,19 +231,22 @@ inline std::ostream /* legacy rect stuff */ -struct NRMatrix; - /* NULL rect is infinite */ struct NRRect { - NRRect() {} + NRRect() + : x0(0), y0(0), x1(0), y1(0) + {} NRRect(NR::Coord xmin, NR::Coord ymin, NR::Coord xmax, NR::Coord ymax) - : x0(xmin), y0(ymin), x1(xmin), y1(ymin) + : x0(xmin), y0(ymin), x1(xmax), y1(ymax) {} explicit NRRect(NR::Rect const &rect); - explicit NRRect(NR::Maybe const &rect); - operator NR::Maybe() const { return upgrade(); } - NR::Maybe upgrade() const; + explicit NRRect(boost::optional const &rect); + operator boost::optional() const { return upgrade(); } + boost::optional upgrade() const; + explicit NRRect(Geom::OptRect const &rect); + operator Geom::OptRect() const { return upgrade_2geom(); } + Geom::OptRect upgrade_2geom() const; NR::Coord x0, y0, x1, y1; }; @@ -264,15 +254,26 @@ struct NRRect { #define nr_rect_d_set_empty(r) (*(r) = NR_RECT_EMPTY) #define nr_rect_l_set_empty(r) (*(r) = NR_RECT_L_EMPTY) -#define nr_rect_d_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) -#define nr_rect_l_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) +/** "Empty" here includes the case of zero width or zero height. */ +// TODO convert to static overloaded functions (pointer and ref) once performance can be tested: +#define nr_rect_d_test_empty_ptr(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) +#define nr_rect_d_test_empty(r) NR_RECT_DFLS_TEST_EMPTY_REF(r) + +// TODO convert to static overloaded functions (pointer and ref) once performance can be tested: +#define nr_rect_l_test_empty_ptr(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) +#define nr_rect_l_test_empty(r) NR_RECT_DFLS_TEST_EMPTY_REF(r) #define nr_rect_d_test_intersect(r0,r1) \ (!nr_rect_d_test_empty(r0) && !nr_rect_d_test_empty(r1) && \ !((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1))) + +// TODO convert to static overloaded functions (pointer and ref) once performance can be tested: +#define nr_rect_l_test_intersect_ptr(r0,r1) \ + (!nr_rect_l_test_empty_ptr(r0) && !nr_rect_l_test_empty_ptr(r1) && \ + !((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1))) #define nr_rect_l_test_intersect(r0,r1) \ (!nr_rect_l_test_empty(r0) && !nr_rect_l_test_empty(r1) && \ - !((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1))) + !(!NR_RECT_DFLS_TEST_INTERSECT_REF(r0, r1))) #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)))) #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)))) @@ -296,7 +297,7 @@ NRRect *nr_rect_d_union_xy(NRRect *d, NR::Coord x, NR::Coord y); NRRectL *nr_rect_l_union_xy(NRRectL *d, NR::ICoord x, NR::ICoord y); NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NR::Matrix const &m); -NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NRMatrix const *m); +NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NR::Matrix const *m); NRRectL *nr_rect_l_enlarge(NRRectL *d, int amount);