xref: /reactos/win32ss/user/user32/windows/rect.c (revision 4a7f3bdb)
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*
20  * PROJECT:         ReactOS user32.dll
21  * FILE:            win32ss/user/user32/windows/rect.c
22  * PURPOSE:         Input
23  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
24  * UPDATE HISTORY:
25  *      09-05-2001  CSH  Created
26  */
27 
28 #include <user32.h>
29 
30 /*
31  * @implemented
32  */
33 BOOL
34 WINAPI
35 CopyRect(LPRECT lprcDst,
36          CONST RECT *lprcSrc)
37 {
38     if (lprcDst == NULL || lprcSrc == NULL)
39         return FALSE;
40 
41     *lprcDst = *lprcSrc;
42 
43     return TRUE;
44 }
45 
46 
47 /*
48  * @implemented
49  */
50 BOOL
51 WINAPI
52 EqualRect(CONST RECT *lprc1,
53           CONST RECT *lprc2)
54 {
55     if (lprc1 == NULL || lprc2 == NULL)
56         return FALSE;
57 
58     return (lprc1->left == lprc2->left) && (lprc1->top == lprc2->top) &&
59            (lprc1->right == lprc2->right) && (lprc1->bottom == lprc2->bottom);
60 }
61 
62 
63 /*
64  * @implemented
65  */
66 BOOL
67 WINAPI
68 InflateRect(LPRECT rect,
69             int dx,
70             int dy)
71 {
72     if (rect == NULL)
73         return FALSE;
74 
75     rect->left -= dx;
76     rect->top -= dy;
77     rect->right += dx;
78     rect->bottom += dy;
79 
80     return TRUE;
81 }
82 
83 
84 /*
85  * @implemented
86  */
87 BOOL
88 WINAPI
89 IntersectRect(LPRECT lprcDst,
90               CONST RECT *lprcSrc1,
91               CONST RECT *lprcSrc2)
92 {
93     if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
94         return FALSE;
95 
96     if (IsRectEmpty(lprcSrc1) || IsRectEmpty(lprcSrc2) ||
97         lprcSrc1->left >= lprcSrc2->right ||
98         lprcSrc2->left >= lprcSrc1->right ||
99         lprcSrc1->top >= lprcSrc2->bottom ||
100         lprcSrc2->top >= lprcSrc1->bottom)
101     {
102         SetRectEmpty(lprcDst);
103         return FALSE;
104     }
105 
106     lprcDst->left = max(lprcSrc1->left, lprcSrc2->left);
107     lprcDst->right = min(lprcSrc1->right, lprcSrc2->right);
108     lprcDst->top = max(lprcSrc1->top, lprcSrc2->top);
109     lprcDst->bottom = min(lprcSrc1->bottom, lprcSrc2->bottom);
110 
111     return TRUE;
112 }
113 
114 
115 /*
116  * @implemented
117  */
118 BOOL
119 WINAPI
120 IsRectEmpty(CONST RECT *lprc)
121 {
122     if (lprc == NULL)
123         return TRUE;
124 
125     return ((lprc->left >= lprc->right) || (lprc->top >= lprc->bottom));
126 }
127 
128 
129 /*
130  * @implemented
131  */
132 BOOL
133 WINAPI
134 OffsetRect(LPRECT rect,
135            int dx,
136            int dy)
137 {
138     if (rect == NULL)
139         return FALSE;
140 
141     rect->left += dx;
142     rect->top += dy;
143     rect->right += dx;
144     rect->bottom += dy;
145 
146     return TRUE;
147 }
148 
149 
150 /*
151  * @implemented
152  */
153 BOOL
154 WINAPI
155 PtInRect(CONST RECT *lprc,
156          POINT pt)
157 {
158     if (lprc == NULL)
159         return FALSE;
160 
161     return((pt.x >= lprc->left) && (pt.x < lprc->right) &&
162            (pt.y >= lprc->top) && (pt.y < lprc->bottom));
163 }
164 
165 BOOL
166 WINAPI
167 SetRect(LPRECT lprc,
168         int xLeft,
169         int yTop,
170         int xRight,
171         int yBottom)
172 {
173     if (lprc == NULL)
174         return FALSE;
175 
176     lprc->left = xLeft;
177     lprc->top = yTop;
178     lprc->right = xRight;
179     lprc->bottom = yBottom;
180 
181     return TRUE;
182 }
183 
184 
185 /*
186  * @implemented
187  */
188 BOOL
189 WINAPI
190 SetRectEmpty(LPRECT lprc)
191 {
192     if (lprc == NULL)
193         return FALSE;
194 
195     lprc->left = lprc->right = lprc->top = lprc->bottom = 0;
196 
197     return TRUE;
198 }
199 
200 
201 /*
202  * @implemented
203  */
204 BOOL
205 WINAPI
206 SubtractRect(LPRECT lprcDst,
207              CONST RECT *lprcSrc1,
208              CONST RECT *lprcSrc2)
209 {
210     RECT tempRect;
211 
212     if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
213         return FALSE;
214 
215     if (!IntersectRect(&tempRect, lprcSrc1, lprcSrc2))
216     {
217         *lprcDst = *lprcSrc1;
218         return TRUE;
219     }
220 
221     if (EqualRect(&tempRect, lprcSrc1))
222     {
223         SetRectEmpty(lprcDst);
224         return FALSE;
225     }
226 
227     *lprcDst = *lprcSrc1;
228 
229     if (lprcDst->top == tempRect.top && lprcDst->bottom == tempRect.bottom)
230     {
231         if (lprcDst->left == tempRect.left)
232             lprcDst->left = tempRect.right;
233         else if (lprcDst->right == tempRect.right)
234             lprcDst->right = tempRect.left;
235     }
236     else if (lprcDst->left == tempRect.left && lprcDst->right == tempRect.right)
237     {
238         if (lprcDst->top == tempRect.top)
239             lprcDst->top = tempRect.bottom;
240         else if (lprcDst->bottom == tempRect.bottom)
241             lprcDst->bottom = tempRect.top;
242     }
243 
244     return TRUE;
245 }
246 
247 
248 /*
249  * @implemented
250  */
251 BOOL
252 WINAPI
253 UnionRect(LPRECT lprcDst,
254           CONST RECT *lprcSrc1,
255           CONST RECT *lprcSrc2)
256 {
257     if (lprcDst == NULL || lprcSrc1 == NULL || lprcSrc2 == NULL)
258         return FALSE;
259 
260     if (IsRectEmpty(lprcSrc1))
261     {
262         if (IsRectEmpty(lprcSrc2))
263         {
264             SetRectEmpty(lprcDst);
265             return FALSE;
266         }
267         else
268         {
269             *lprcDst = *lprcSrc2;
270         }
271     }
272     else
273     {
274         if (IsRectEmpty(lprcSrc2))
275         {
276             *lprcDst = *lprcSrc1;
277         }
278         else
279         {
280             lprcDst->left = min(lprcSrc1->left, lprcSrc2->left);
281             lprcDst->top = min(lprcSrc1->top, lprcSrc2->top);
282             lprcDst->right = max(lprcSrc1->right, lprcSrc2->right);
283             lprcDst->bottom = max(lprcSrc1->bottom, lprcSrc2->bottom);
284         }
285     }
286 
287     return TRUE;
288 }
289