Code

Fix behavior when loading a document
[inkscape.git] / src / libnr / nr-rect.h
index 2439df95d3361dde016a240eb35f3e518fd0386e..c074b00347c34160ea1bee9e6da0bb5f25128c7e 100644 (file)
 #include <libnr/nr-i-coord.h>
 #include <libnr/nr-dim2.h>
 #include <libnr/nr-point.h>
-#include <libnr/nr-maybe.h>
+#include <boost/optional.hpp>
 #include <libnr/nr-point-matrix-ops.h>
-
-struct NRRect;
-struct NRRectL;
+#include <libnr/nr-forward.h>
+#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
@@ -42,8 +40,6 @@ class Rect {
 public:
     Rect() : _min(-_inf(), -_inf()), _max(_inf(), _inf()) {}
     Rect(Point const &p0, Point const &p1);
-    Rect(NRRect *r);
-    Rect(NRRectL *r);
 
     Point const &min() const { return _min; }
     Point const &max() const { return _max; }
@@ -58,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<X>(epsilon) || isEmpty<Y>(epsilon);
     }
@@ -149,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<double>::infinity();
@@ -182,47 +181,30 @@ private:
 
     Point _min, _max;
 
-    friend class MaybeStorage<Rect>;
-    friend Maybe<Rect> intersection(Maybe<Rect> const &, Maybe<Rect> const &);
+    friend boost::optional<Rect> intersection(boost::optional<Rect> const &, boost::optional<Rect> const &);
     friend Rect union_bounds(Rect const &, Rect const &);
 };
 
-template <>
-class MaybeStorage<Rect> {
-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<Rect> intersection(Maybe<Rect> const & a, Maybe<Rect> const & b);
+boost::optional<Rect> intersection(boost::optional<Rect> const & a, boost::optional<Rect> const & b);
 
 /** Returns the smallest rectangle that encloses both rectangles. */
 Rect union_bounds(Rect const &a, Rect const &b);
-inline Rect union_bounds(Maybe<Rect> const & a, Rect const &b) {
+inline Rect union_bounds(boost::optional<Rect> const & a, Rect const &b) {
     if (a) {
         return union_bounds(*a, b);
     } else {
         return b;
     }
 }
-inline Rect union_bounds(Rect const &a, Maybe<Rect> const & b) {
+inline Rect union_bounds(Rect const &a, boost::optional<Rect> const & b) {
     if (b) {
         return union_bounds(a, *b);
     } else {
         return a;
     }
 }
-inline Maybe<Rect> union_bounds(Maybe<Rect> const & a, Maybe<Rect> const & b)
+inline boost::optional<Rect> union_bounds(boost::optional<Rect> const & a, boost::optional<Rect> const & b)
 {
     if (!a) {
         return b;
@@ -249,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<NR::Rect> const &rect);
-    operator NR::Maybe<NR::Rect>() const { return upgrade(); }
-    NR::Maybe<NR::Rect> upgrade() const;
+    explicit NRRect(boost::optional<NR::Rect> const &rect);
+    operator boost::optional<NR::Rect>() const { return upgrade(); }
+    boost::optional<NR::Rect> 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;
 };
@@ -269,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))))
@@ -301,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);