1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright 2007 Novell, Inc. (http://www.novell.com)
7 * See the LICENSE file included with the distribution for details.
11 #ifndef __MOON_RECT_H__
12 #define __MOON_RECT_H__
17 #include <gdk/gdk.h> // for GdkRectangle
20 #include "thickness.h"
21 #include "cornerradius.h"
23 // map to System.Windows.Rect
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
)
39 this->height
= height
;
42 Rect (const Point
& p1
, const Point
& p2
)
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
));
69 return IsEmpty (false);
72 bool IsEmpty (bool logical
) const
75 return ((width
<= 0.0) && (height
<= 0.0));
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
);
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
))
103 if ((rect
.width
<= 0.0) && (rect
.height
<= 0.0))
106 if ((rect
.width
<= 0.0) || (rect
.height
<= 0.0))
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
;
117 Rect
RoundOut () const
119 Rect
result (floor (x
), floor (y
), ceil (x
+ width
) - floor (x
), ceil (y
+ height
) - floor (y
));
123 Rect
RoundIn () const
125 Rect
result (ceil (x
), ceil (y
), floor (x
+ width
) - ceil (x
), floor (y
+ height
) - ceil (y
));
129 Rect
GrowBy (double left
, double top
, double right
, double bottom
) const
134 result
.width
+= left
+ right
;
135 result
.height
+= top
+ bottom
;
137 if (result
.width
< 0)
140 if (result
.height
< 0)
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
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
);
174 Rect
ExtendTo (const Point
& p
)
176 return ExtendTo (p
.x
, p
.y
);
180 ToGdkRectangle () const
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
;
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
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
);
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__ */