Code

Disable the page selector when there's only one page
[inkscape.git] / src / libnr / nr-rect.cpp
index 6d881e7b0a75fac20b9740d84bb8862c2b521d8c..72bced37bb048ca9337d8c03658710f412c2dd81 100644 (file)
  */
 
 #include "nr-rect-l.h"
+#include <algorithm>
+
+NRRect::NRRect(NR::Rect const &rect)
+: x0(rect.min()[NR::X]), y0(rect.min()[NR::Y]),
+  x1(rect.max()[NR::X]), y1(rect.max()[NR::Y])
+{}
+
+NRRect::NRRect(NR::Maybe<NR::Rect> const &rect) {
+    if (rect) {
+        x0 = rect->min()[NR::X];
+        y0 = rect->min()[NR::Y];
+        x1 = rect->max()[NR::X];
+        y1 = rect->max()[NR::Y];
+    } else {
+        nr_rect_d_set_empty(this);
+    }
+}
+
+NR::Maybe<NR::Rect> NRRect::upgrade() const {
+    if (nr_rect_d_test_empty(this)) {
+        return NR::Nothing();
+    } else {
+        return NR::Rect(NR::Point(x0, y0), NR::Point(x1, y1));
+    }
+}
 
 /**
  *    \param r0 Rectangle.
@@ -45,6 +70,60 @@ nr_rect_d_intersect (NRRect *d, const NRRect *r0, const NRRect *r1)
        return d;
 }
 
+// returns minimal rect which covers all of r0 not covered by r1
+NRRectL *
+nr_rect_l_subtract(NRRectL *d, NRRectL const *r0, NRRectL const *r1)
+{
+    bool inside1 = nr_rect_l_test_inside(r1, r0->x0, r0->y0);
+    bool inside2 = nr_rect_l_test_inside(r1, r0->x1, r0->y0);
+    bool inside3 = nr_rect_l_test_inside(r1, r0->x1, r0->y1);
+    bool inside4 = nr_rect_l_test_inside(r1, r0->x0, r0->y1);
+
+    if (inside1 && inside2 && inside3) {
+        nr_rect_l_set_empty (d);
+
+    } else if (inside1 && inside2) {
+        d->x0 = r0->x0;
+        d->y0 = r1->y1;
+
+        d->x1 = r0->x1;
+        d->y1 = r0->y1;
+    } else if (inside2 && inside3) {
+        d->x0 = r0->x0;
+        d->y0 = r0->y0;
+
+        d->x1 = r1->x0;
+        d->y1 = r0->y1;
+    } else if (inside3 && inside4) {
+        d->x0 = r0->x0;
+        d->y0 = r0->y0;
+
+        d->x1 = r0->x1;
+        d->y1 = r1->y0;
+    } else if (inside4 && inside1) {
+        d->x0 = r1->x1;
+        d->y0 = r0->y0;
+
+        d->x1 = r0->x1;
+        d->y1 = r0->y1;
+    } else {
+        d->x0 = r0->x0;
+        d->y0 = r0->y0;
+
+        d->x1 = r0->x1;
+        d->y1 = r0->y1;
+    }
+    return d;
+}
+
+NR::ICoord nr_rect_l_area(NRRectL *r)
+{
+  if (!r || NR_RECT_DFLS_TEST_EMPTY (r)) {
+      return 0;
+  }
+  return ((r->x1 - r->x0) * (r->y1 - r->y0));
+}
+
 NRRect *
 nr_rect_d_union (NRRect *d, const NRRect *r0, const NRRect *r1)
 {
@@ -164,8 +243,9 @@ nr_rect_l_enlarge(NRRectL *d, int amount)
 namespace NR {
 
 Rect::Rect(const Point &p0, const Point &p1)
-: _min(MIN(p0[X], p1[X]), MIN(p0[Y], p1[Y])),
-  _max(MAX(p0[X], p1[X]), MAX(p0[Y], p1[Y])) {}
+: _min(std::min(p0[X], p1[X]), std::min(p0[Y], p1[Y])),
+  _max(std::max(p0[X], p1[X]), std::max(p0[Y], p1[Y]))
+{}
 
 /** returns the four corners of the rectangle in the correct winding order */
 Point Rect::corner(unsigned i) const {
@@ -200,33 +280,46 @@ void Rect::offset(Point p) {
 /** Makes this rectangle large enough to include the point p. */
 void Rect::expandTo(Point p) {
        for ( int i=0 ; i < 2 ; i++ ) {
-               _min[i] = MIN(_min[i], p[i]);
-               _max[i] = MAX(_max[i], p[i]);
+               _min[i] = std::min(_min[i], p[i]);
+               _max[i] = std::max(_max[i], p[i]);
        }
 }
 
-/** Returns the set of points shared by both rectangles. */
-Maybe<Rect> Rect::intersection(const Rect &a, const Rect &b) {
-       Rect r;
-       for ( int i=0 ; i < 2 ; i++ ) {
-               r._min[i] = MAX(a._min[i], b._min[i]);
-               r._max[i] = MIN(a._max[i], b._max[i]);
+void Rect::growBy(double size) {
+  for ( unsigned d = 0 ; d < 2 ; d++ ) {
+    _min[d] -= size;
+    _max[d] += size;
+    if ( _min[d] > _max[d] ) {
+      _min[d] = _max[d] = ( _min[d] + _max[d] ) / 2;
+    }
+  }
+} 
 
-               if ( r._min[i] > r._max[i] ) {
-                       return Nothing();
-               }
+/** Returns the set of points shared by both rectangles. */
+Maybe<Rect> intersection(Maybe<Rect> const & a, Maybe<Rect> const & b) {
+    if ( !a || !b ) {
+        return Nothing();
+    } else {
+        Rect r;
+        for ( int i=0 ; i < 2 ; i++ ) {
+            r._min[i] = std::max(a->_min[i], b->_min[i]);
+            r._max[i] = std::min(a->_max[i], b->_max[i]);
+            if ( r._min[i] > r._max[i] ) {
+               return Nothing();
+            }
        }
        return r;
+    }
 }
 
 /** returns the smallest rectangle containing both rectangles */
-Rect Rect::union_bounds(const Rect &a, const Rect &b) {
-       Rect r;
-       for ( int i=0; i < 2 ; i++ ) {
-               r._min[i] = MIN(a._min[i], b._min[i]);
-               r._max[i] = MAX(a._max[i], b._max[i]);
-       }
-       return r;
+Rect union_bounds(Rect const &a, Rect const &b) {
+    Rect r;
+    for ( int i=0 ; i < 2 ; i++ ) {
+        r._min[i] = std::min(a._min[i], b._min[i]);
+        r._max[i] = std::max(a._max[i], b._max[i]);
+    }
+    return r;
 }
 
 }  // namespace NR