2009-10-09 Chris Toshok <toshok@ximian.com>
[moon.git] / src / rect.h
blob9c46d93ff07f633357da962b19c51efb7a40cb23
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * rect.h
5 * Copyright 2007 Novell, Inc. (http://www.novell.com)
7 * See the LICENSE file included with the distribution for details.
8 *
9 */
11 #ifndef __MOON_RECT_H__
12 #define __MOON_RECT_H__
14 #include <glib.h>
15 #include <cairo.h>
16 #include <math.h>
17 #include <gdk/gdk.h> // for GdkRectangle
19 #include "point.h"
20 #include "thickness.h"
21 #include "cornerradius.h"
23 // map to System.Windows.Rect
24 /* @IncludeInKinds */
25 struct Rect {
26 public:
27 double x, y, width, height;
29 Rect () : x (0), y (0), width (0), height (0) {}
31 // to please the current generator when used for a return value
32 Rect (int zero) : x (0), y (0), width (0), height (0) {}
34 Rect (double x, double y, double width, double height)
36 this->x = x;
37 this->y = y;
38 this->width = width;
39 this->height = height;
42 Rect (const Point& p1, const Point& p2)
44 x = MIN (p1.x, p2.x);
45 y = MIN (p1.y, p2.y);
46 width = ABS (p1.x - p2.x);
47 height = ABS (p1.y - p2.y);
50 Rect Transform (cairo_matrix_t *matrix);
52 bool PointInside (double px, double py) const
54 return px >= x && px < (x + width) && py >= y && py < (y + height);
57 bool PointInside (const Point& p) const
59 return p.x >= x && p.x < (x + width) && p.y >= y && p.y < (y + height);
62 bool IntersectsWith (const Rect& rect) const
64 return ((x < rect.x + rect.width) && (x + width > rect.x) && (y < rect.y + rect.height) && (y + height > rect.y));
67 bool IsEmpty () const
69 return IsEmpty (false);
72 bool IsEmpty (bool logical) const
74 if (logical)
75 return ((width <= 0.0) && (height <= 0.0));
76 else
77 return ((width <= 0.0) || (height <= 0.0));
80 Rect Intersection (const Rect& rect) const
82 Rect result = Rect ();
83 result.x = x > rect.x ? x : rect.x;
84 result.y = y > rect.y ? y : rect.y;
85 result.width = MAX (0, ((x + width < rect.x + rect.width) ? (x + width) : (rect.x + rect.width)) - result.x);
86 result.height = MAX (0, ((y + height < rect.y + rect.height) ? (y + height) : (rect.y + rect.height)) - result.y);
87 return result;
90 Rect Union (const Rect& rect) const
92 return Union (rect, false);
95 // Note about the logical bool: there's now an override for both Rect::Union and
96 // Rect::IsEmpty that takes a bool. That bool allows union of rectangle with one
97 // empty extend. This is needed to compute logical bounds for example.
98 Rect Union (const Rect& rect, bool logical) const
100 if (IsEmpty (logical))
101 return Rect (rect);
102 if (logical) {
103 if ((rect.width <= 0.0) && (rect.height <= 0.0))
104 return Rect (*this);
105 } else {
106 if ((rect.width <= 0.0) || (rect.height <= 0.0))
107 return Rect (*this);
109 Rect result = Rect ();
110 result.x = x < rect.x ? x : rect.x;
111 result.y = y < rect.y ? y : rect.y;
112 result.width = ((x + width > rect.x + rect.width) ? (x + width) : (rect.x + rect.width)) - result.x;
113 result.height = ((y + height > rect.y + rect.height) ? (y + height) : (rect.y + rect.height)) - result.y;
114 return result;
117 Rect RoundOut () const
119 Rect result (floor (x), floor (y), ceil (x + width) - floor (x), ceil (y + height) - floor (y));
120 return result;
123 Rect RoundIn () const
125 Rect result (ceil (x), ceil (y), floor (x + width) - ceil (x), floor (y + height) - ceil (y));
126 return result;
129 Rect GrowBy (double left, double top, double right, double bottom) const
131 Rect result = *this;
132 result.x -= left;
133 result.y -= top;
134 result.width += left + right;
135 result.height += top + bottom;
137 if (result.width < 0)
138 result.width = 0;
140 if (result.height < 0)
141 result.height = 0;
143 return result;
146 Rect GrowBy (double xd, double yd) const
148 return GrowBy (xd, yd, xd, yd);
151 Rect GrowBy (double d) const
153 return GrowBy (d, d, d, d);
156 Rect GrowBy (const Thickness &t) const
158 return GrowBy (t.left, t.top, t.right, t.bottom);
161 Rect ExtendTo (double x, double y) const
163 Rect result = *this;
164 if (x < result.x || x > (result.x + result.width))
165 result.width = MAX (ABS(x - result.x), ABS(x - result.x - result.width));
166 if (y < result.y || y > (result.y + result.height))
167 result.height = MAX (ABS(y - result.y), ABS(y - result.y - result.height));
168 result.x = MIN (result.x, x);
169 result.y = MIN (result.y, y);
171 return result;
174 Rect ExtendTo (const Point& p)
176 return ExtendTo (p.x, p.y);
179 GdkRectangle
180 ToGdkRectangle () const
182 GdkRectangle gdk;
183 Rect rect = RoundOut ();
184 gdk.x = (gint)rect.x;
185 gdk.y = (gint)rect.y;
186 gdk.width = (gint)rect.width;
187 gdk.height = (gint)rect.height;
189 return gdk;
192 bool operator == (const Rect &rect)
194 return fabs(x-rect.x) < DBL_EPSILON && fabs(y-rect.y) < DBL_EPSILON && fabs(width-rect.width) < DBL_EPSILON && fabs(height-rect.height) < DBL_EPSILON;
197 bool operator != (const Rect &rect)
199 return !(*this == rect);
202 void Draw (cairo_t *cr) const
204 cairo_rectangle (cr, x, y, width, height);
208 void Draw (cairo_t *cr, CornerRadius *round) const;
210 Point GetTopLeft () const
212 return Point (x, y);
215 Point GetTopRight () const
217 return Point (x + width, y);
220 Point GetBottomLeft () const
222 return Point (x, y + height);
225 Point GetBottomRight () const
227 return Point (x + width, y + height);
231 // FromStr
232 // Parses @s and return a new rect in @r. Returns true if
233 // this was successful, false otherwise.
235 static bool FromStr (const char *s, Rect *r);
238 #endif /* __MOON_RECT_H__ */