Merge branch 'blender2.7'
[blender.git] / intern / ghost / GHOST_Rect.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup GHOST
21  * Macro's used in GHOST debug target.
22  */
23
24 #ifndef __GHOST_RECT_H__
25 #define __GHOST_RECT_H__
26
27 #include "GHOST_Types.h"
28
29
30 /**
31  * Implements rectangle functionality.
32  * The four extreme coordinates are stored as left, top, right and bottom.
33  * To be valid, a rectangle should have a left coordinate smaller than or equal to right.
34  * To be valid, a rectangle should have a top coordinate smaller than or equal to bottom.
35  */
36
37 class GHOST_Rect {
38 public:
39
40         /**
41          * Constructs a rectangle with the given values.
42          * \param l requested left coordinate of the rectangle
43          * \param t requested top coordinate of the rectangle
44          * \param r requested right coordinate of the rectangle
45          * \param b requested bottom coordinate of the rectangle
46          */
47         GHOST_Rect(GHOST_TInt32 l = 0, GHOST_TInt32 t = 0, GHOST_TInt32 r = 0, GHOST_TInt32 b = 0)
48                 : m_l(l), m_t(t), m_r(r), m_b(b)
49         {}
50
51         /**
52          * Copy constructor.
53          * \param   r   rectangle to copy
54          */
55         GHOST_Rect(const GHOST_Rect& r)
56                 : m_l(r.m_l), m_t(r.m_t), m_r(r.m_r), m_b(r.m_b)
57         {}
58
59         /**
60          * Destructor.
61          */
62         virtual ~GHOST_Rect() {}
63
64         /**
65          * Access to rectangle width.
66          * \return  width of the rectangle
67          */
68         virtual inline GHOST_TInt32 getWidth() const;
69
70         /**
71          * Access to rectangle height.
72          * \return  height of the rectangle
73          */
74         virtual inline GHOST_TInt32 getHeight() const;
75
76         /**
77          * Sets all members of the rectangle.
78          * \param   l   requested left coordinate of the rectangle
79          * \param   t   requested top coordinate of the rectangle
80          * \param   r   requested right coordinate of the rectangle
81          * \param   b   requested bottom coordinate of the rectangle
82          */
83         virtual inline void set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b);
84
85         /**
86          * Returns whether this rectangle is empty.
87          * Empty rectangles are rectangles that have width==0 and/or height==0.
88          * \return  boolean value (true==empty rectangle)
89          */
90         virtual inline bool isEmpty() const;
91
92         /**
93          * Returns whether this rectangle is valid.
94          * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. Thus, empty rectangles are valid.
95          * \return  boolean value (true==valid rectangle)
96          */
97         virtual inline bool isValid() const;
98
99         /**
100          * Grows (or shrinks the rectangle).
101          * The method avoids negative insets making the rectangle invalid
102          * \param   i   The amount of offset given to each extreme (negative values shrink the rectangle).
103          */
104         virtual void inset(GHOST_TInt32 i);
105
106         /**
107          * Does a union of the rectangle given and this rectangle.
108          * The result is stored in this rectangle.
109          * \param   r   The rectangle that is input for the union operation.
110          */
111         virtual inline void unionRect(const GHOST_Rect& r);
112
113         /**
114          * Grows the rectangle to included a point.
115          * \param   x   The x-coordinate of the point.
116          * \param   y   The y-coordinate of the point.
117          */
118         virtual inline void unionPoint(GHOST_TInt32 x, GHOST_TInt32 y);
119
120         /**
121          * Grows the rectangle to included a point.
122          * \param   x   The x-coordinate of the point.
123          * \param   y   The y-coordinate of the point.
124          */
125         virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs);
126
127         /**
128          * Returns whether the point is inside this rectangle.
129          * Point on the boundary is considered inside.
130          * \param x x-coordinate of point to test.
131          * \param y y-coordinate of point to test.
132          * \return boolean value (true if point is inside).
133          */
134         virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const;
135
136         /**
137          * Returns whether the rectangle is inside this rectangle.
138          * \param   r   rectangle to test.
139          * \return  visibility (not, partially or fully visible).
140          */
141         virtual GHOST_TVisibility getVisibility(GHOST_Rect& r) const;
142
143         /**
144          * Sets rectangle members.
145          * Sets rectangle members such that it is centered at the given location.
146          * \param   cx  requested center x-coordinate of the rectangle
147          * \param   cy  requested center y-coordinate of the rectangle
148          */
149         virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy);
150
151         /**
152          * Sets rectangle members.
153          * Sets rectangle members such that it is centered at the given location,
154          * with the width requested.
155          * \param   cx  requested center x-coordinate of the rectangle
156          * \param   cy  requested center y-coordinate of the rectangle
157          * \param   w   requested width of the rectangle
158          * \param   h   requested height of the rectangle
159          */
160         virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h);
161
162         /**
163          * Clips a rectangle.
164          * Updates the rectangle given such that it will fit within this one.
165          * This can result in an empty rectangle.
166          * \param   r   the rectangle to clip
167          * \return  whether clipping has occurred
168          */
169         virtual bool clip(GHOST_Rect& r) const;
170
171         /** Left coordinate of the rectangle */
172         GHOST_TInt32 m_l;
173         /** Top coordinate of the rectangle */
174         GHOST_TInt32 m_t;
175         /** Right coordinate of the rectangle */
176         GHOST_TInt32 m_r;
177         /** Bottom coordinate of the rectangle */
178         GHOST_TInt32 m_b;
179
180 #ifdef WITH_CXX_GUARDEDALLOC
181         MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Rect")
182 #endif
183 };
184
185
186 inline GHOST_TInt32 GHOST_Rect::getWidth() const
187 {
188         return m_r - m_l;
189 }
190
191 inline GHOST_TInt32 GHOST_Rect::getHeight() const
192 {
193         return m_b - m_t;
194 }
195
196 inline void GHOST_Rect::set(GHOST_TInt32 l, GHOST_TInt32 t, GHOST_TInt32 r, GHOST_TInt32 b)
197 {
198         m_l = l; m_t = t; m_r = r; m_b = b;
199 }
200
201 inline bool GHOST_Rect::isEmpty() const
202 {
203         return (getWidth() == 0) || (getHeight() == 0);
204 }
205
206 inline bool GHOST_Rect::isValid() const
207 {
208         return (m_l <= m_r) && (m_t <= m_b);
209 }
210
211 inline void GHOST_Rect::unionRect(const GHOST_Rect& r)
212 {
213         if (r.m_l < m_l) m_l = r.m_l;
214         if (r.m_r > m_r) m_r = r.m_r;
215         if (r.m_t < m_t) m_t = r.m_t;
216         if (r.m_b > m_b) m_b = r.m_b;
217 }
218
219 inline void GHOST_Rect::unionPoint(GHOST_TInt32 x, GHOST_TInt32 y)
220 {
221         if (x < m_l) m_l = x;
222         if (x > m_r) m_r = x;
223         if (y < m_t) m_t = y;
224         if (y > m_b) m_b = y;
225 }
226 #include <stdio.h>
227 inline void GHOST_Rect::wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, GHOST_TInt32 ofs)
228 {
229         GHOST_TInt32 w = getWidth();
230         GHOST_TInt32 h = getHeight();
231
232         /* highly unlikely but avoid eternal loop */
233         if (w - ofs * 2 <= 0 || h - ofs * 2 <= 0) {
234                 return;
235         }
236
237         while (x - ofs < m_l) x += w - (ofs * 2);
238         while (y - ofs < m_t) y += h - (ofs * 2);
239         while (x + ofs > m_r) x -= w - (ofs * 2);
240         while (y + ofs > m_b) y -= h - (ofs * 2);
241 }
242
243 inline bool GHOST_Rect::isInside(GHOST_TInt32 x, GHOST_TInt32 y) const
244 {
245         return (x >= m_l) && (x <= m_r) && (y >= m_t) && (y <= m_b);
246 }
247
248 #endif // __GHOST_RECT_H__