+ boost::optional<Rect> intersection (Rect const & o) const throw () {
+ Rect i (std::max (x0, o.x0), std::max (y0, o.y0),
+ std::min (x1, o.x1), std::min (y1, o.y1));
+
+ if (i.x0 > i.x1 || i.y0 > i.y1) {
+ return boost::optional<Rect> ();
+ }
+
+ return boost::optional<Rect> (i);
+ }
+
+ Rect extend (Rect const & o) const throw () {
+ return Rect (std::min (x0, o.x0), std::min (y0, o.y0),
+ std::max (x1, o.x1), std::max (y1, o.y1));
+ }
+ Rect translate (Duple const& t) const throw () {
+ return Rect (canvas_safe_add (x0, t.x), canvas_safe_add (y0, t.y),
+ canvas_safe_add (x1, t.x),canvas_safe_add (y1, t.y));
+ }
+ Rect expand (Distance amount) const throw () {
+ return Rect (x0 - amount, y0 - amount,
+ canvas_safe_add (x1, amount),
+ canvas_safe_add (y1, amount));
+ }
+
+ Rect shrink (Distance amount) const throw () {
+ /* This isn't the equivalent of expand (-distance) because
+ of the peculiarities of canvas_safe_add() with negative values.
+ Maybe.
+ */
+ return Rect (canvas_safe_add (x0, amount), canvas_safe_add (y0, amount),
+ x1 - amount, y1 - amount);
+ }
+
+ bool contains (Duple const & point) const throw () {
+ return point.x >= x0 && point.x < x1 && point.y >= y0 && point.y < y1;
+ }
+ Rect fix () const throw () {
+ return Rect (std::min (x0, x1), std::min (y0, y1),
+ std::max (x0, x1), std::max (y0, y1));
+ }
+
+ bool empty() const throw () { return (x0 == x1 && y0 == y1); }