Make sure that functions returning an HWND always return a full 32-bit
[wine] / windows / rect.c
1 /*
2  * Rectangle-related functions
3  *
4  * Copyright 1993, 1996 Alexandre Julliard
5  *
6  */
7
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "wine/winuser16.h"
11 #include "winuser.h"
12
13 /***********************************************************************
14  *              SetRect (USER.72)
15  */
16 void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top,
17                        INT16 right, INT16 bottom )
18 {
19     rect->left   = left;
20     rect->right  = right;
21     rect->top    = top;
22     rect->bottom = bottom;
23 }
24
25
26 /***********************************************************************
27  *              SetRect (USER32.@)
28  */
29 BOOL WINAPI SetRect( LPRECT rect, INT left, INT top,
30                        INT right, INT bottom )
31 {
32     rect->left   = left;
33     rect->right  = right;
34     rect->top    = top;
35     rect->bottom = bottom;
36     return TRUE;
37 }
38
39
40 /***********************************************************************
41  *              SetRectEmpty (USER.73)
42  */
43 void WINAPI SetRectEmpty16( LPRECT16 rect )
44 {
45     rect->left = rect->right = rect->top = rect->bottom = 0;
46 }
47
48
49 /***********************************************************************
50  *              SetRectEmpty (USER32.@)
51  */
52 BOOL WINAPI SetRectEmpty( LPRECT rect )
53 {
54     rect->left = rect->right = rect->top = rect->bottom = 0;
55     return TRUE;
56 }
57
58
59 /***********************************************************************
60  *              CopyRect (USER.74)
61  */
62 BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
63 {
64     *dest = *src;
65     return TRUE;
66 }
67
68
69 /***********************************************************************
70  *              CopyRect (USER32.@)
71  */
72 BOOL WINAPI CopyRect( RECT *dest, const RECT *src )
73 {
74     if (!dest || !src)
75         return FALSE;
76     *dest = *src;
77     return TRUE;
78 }
79
80
81 /***********************************************************************
82  *              IsRectEmpty (USER.75)
83  *
84  * Bug compat: Windows checks for 0 or negative width/height.
85  */
86 BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
87 {
88     return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
89 }
90
91
92 /***********************************************************************
93  *              IsRectEmpty (USER32.@)
94  *
95  * Bug compat: Windows checks for 0 or negative width/height.
96  */
97 BOOL WINAPI IsRectEmpty( const RECT *rect )
98 {
99     return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
100 }
101
102
103 /***********************************************************************
104  *              PtInRect (USER.76)
105  */
106 BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
107 {
108     return ((pt.x >= rect->left) && (pt.x < rect->right) &&
109             (pt.y >= rect->top) && (pt.y < rect->bottom));
110 }
111
112
113 /***********************************************************************
114  *              PtInRect (USER32.@)
115  */
116 BOOL WINAPI PtInRect( const RECT *rect, POINT pt )
117 {
118     return ((pt.x >= rect->left) && (pt.x < rect->right) &&
119             (pt.y >= rect->top) && (pt.y < rect->bottom));
120 }
121
122
123 /***********************************************************************
124  *              OffsetRect (USER.77)
125  */
126 void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
127 {
128     rect->left   += x;
129     rect->right  += x;
130     rect->top    += y;
131     rect->bottom += y;    
132 }
133
134
135 /***********************************************************************
136  *              OffsetRect (USER32.@)
137  */
138 BOOL WINAPI OffsetRect( LPRECT rect, INT x, INT y )
139 {
140     rect->left   += x;
141     rect->right  += x;
142     rect->top    += y;
143     rect->bottom += y;    
144     return TRUE;
145 }
146
147
148 /***********************************************************************
149  *              InflateRect (USER.78)
150  */
151 void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
152 {
153     rect->left   -= x;
154     rect->top    -= y;
155     rect->right  += x;
156     rect->bottom += y;
157 }
158
159
160 /***********************************************************************
161  *              InflateRect (USER32.@)
162  */
163 BOOL WINAPI InflateRect( LPRECT rect, INT x, INT y )
164 {
165     rect->left   -= x;
166     rect->top    -= y;
167     rect->right  += x;
168     rect->bottom += y;
169     return TRUE;
170 }
171
172
173 /***********************************************************************
174  *              IntersectRect (USER.79)
175  */
176 BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
177                                const RECT16 *src2 )
178 {
179     if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
180         (src1->left >= src2->right) || (src2->left >= src1->right) ||
181         (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
182     {
183         SetRectEmpty16( dest );
184         return FALSE;
185     }
186     dest->left   = max( src1->left, src2->left );
187     dest->right  = min( src1->right, src2->right );
188     dest->top    = max( src1->top, src2->top );
189     dest->bottom = min( src1->bottom, src2->bottom );
190     return TRUE;
191 }
192
193
194 /***********************************************************************
195  *              IntersectRect (USER32.@)
196  */
197 BOOL WINAPI IntersectRect( LPRECT dest, const RECT *src1,
198                                const RECT *src2 )
199 {
200     if (IsRectEmpty(src1) || IsRectEmpty(src2) ||
201         (src1->left >= src2->right) || (src2->left >= src1->right) ||
202         (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
203     {
204         SetRectEmpty( dest );
205         return FALSE;
206     }
207     dest->left   = max( src1->left, src2->left );
208     dest->right  = min( src1->right, src2->right );
209     dest->top    = max( src1->top, src2->top );
210     dest->bottom = min( src1->bottom, src2->bottom );
211     return TRUE;
212 }
213
214
215 /***********************************************************************
216  *              UnionRect (USER.80)
217  */
218 BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
219                            const RECT16 *src2 )
220 {
221     if (IsRectEmpty16(src1))
222     {
223         if (IsRectEmpty16(src2))
224         {
225             SetRectEmpty16( dest );
226             return FALSE;
227         }
228         else *dest = *src2;
229     }
230     else
231     {
232         if (IsRectEmpty16(src2)) *dest = *src1;
233         else
234         {
235             dest->left   = min( src1->left, src2->left );
236             dest->right  = max( src1->right, src2->right );
237             dest->top    = min( src1->top, src2->top );
238             dest->bottom = max( src1->bottom, src2->bottom );       
239         }
240     }
241     return TRUE;
242 }
243
244
245 /***********************************************************************
246  *              UnionRect (USER32.@)
247  */
248 BOOL WINAPI UnionRect( LPRECT dest, const RECT *src1,
249                            const RECT *src2 )
250 {
251     if (IsRectEmpty(src1))
252     {
253         if (IsRectEmpty(src2))
254         {
255             SetRectEmpty( dest );
256             return FALSE;
257         }
258         else *dest = *src2;
259     }
260     else
261     {
262         if (IsRectEmpty(src2)) *dest = *src1;
263         else
264         {
265             dest->left   = min( src1->left, src2->left );
266             dest->right  = max( src1->right, src2->right );
267             dest->top    = min( src1->top, src2->top );
268             dest->bottom = max( src1->bottom, src2->bottom );       
269         }
270     }
271     return TRUE;
272 }
273
274
275 /***********************************************************************
276  *              EqualRect (USER.244)
277  */
278 BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
279 {
280     return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
281             (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
282 }
283
284
285 /***********************************************************************
286  *              EqualRect (USER32.@)
287  */
288 BOOL WINAPI EqualRect( const RECT* rect1, const RECT* rect2 )
289 {
290     return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
291             (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
292 }
293
294
295 /***********************************************************************
296  *              SubtractRect (USER.373)
297  */
298 BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
299                               const RECT16 *src2 )
300 {
301     RECT16 tmp;
302
303     if (IsRectEmpty16( src1 ))
304     {
305         SetRectEmpty16( dest );
306         return FALSE;
307     }
308     *dest = *src1;
309     if (IntersectRect16( &tmp, src1, src2 ))
310     {
311         if (EqualRect16( &tmp, dest ))
312         {
313             SetRectEmpty16( dest );
314             return FALSE;
315         }
316         if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
317         {
318             if (tmp.left == dest->left) dest->left = tmp.right;
319             else if (tmp.right == dest->right) dest->right = tmp.left;
320         }
321         else if ((tmp.left == dest->left) && (tmp.right == dest->right))
322         {
323             if (tmp.top == dest->top) dest->top = tmp.bottom;
324             else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
325         }
326     }
327     return TRUE;
328 }
329
330
331 /***********************************************************************
332  *              SubtractRect (USER32.@)
333  */
334 BOOL WINAPI SubtractRect( LPRECT dest, const RECT *src1,
335                               const RECT *src2 )
336 {
337     RECT tmp;
338
339     if (IsRectEmpty( src1 ))
340     {
341         SetRectEmpty( dest );
342         return FALSE;
343     }
344     *dest = *src1;
345     if (IntersectRect( &tmp, src1, src2 ))
346     {
347         if (EqualRect( &tmp, dest ))
348         {
349             SetRectEmpty( dest );
350             return FALSE;
351         }
352         if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
353         {
354             if (tmp.left == dest->left) dest->left = tmp.right;
355             else if (tmp.right == dest->right) dest->right = tmp.left;
356         }
357         else if ((tmp.left == dest->left) && (tmp.right == dest->right))
358         {
359             if (tmp.top == dest->top) dest->top = tmp.bottom;
360             else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
361         }
362     }
363     return TRUE;
364 }