2 * Unit test suite for clipping
4 * Copyright 2005 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
26 static void test_GetRandomRgn(void)
28 HWND hwnd
= CreateWindowExA(0,"BUTTON","test",WS_VISIBLE
|WS_POPUP
,0,0,100,100,GetDesktopWindow(),0,0,0);
30 HRGN hrgn
= CreateRectRgn(0, 0, 0, 0);
33 RECT ret_rc
, window_rc
;
35 ok( hwnd
!= 0, "CreateWindow failed\n" );
37 SetRect(&window_rc
, 400, 300, 500, 400);
38 SetWindowPos(hwnd
, HWND_TOPMOST
, window_rc
.left
, window_rc
.top
,
39 window_rc
.right
- window_rc
.left
, window_rc
.bottom
- window_rc
.top
, 0 );
42 ret
= GetRandomRgn(hdc
, hrgn
, 1);
43 ok(ret
== 0, "GetRandomRgn rets %d\n", ret
);
44 ret
= GetRandomRgn(hdc
, hrgn
, 2);
45 ok(ret
== 0, "GetRandomRgn rets %d\n", ret
);
46 ret
= GetRandomRgn(hdc
, hrgn
, 3);
47 ok(ret
== 0, "GetRandomRgn rets %d\n", ret
);
49 /* Set a clip region */
50 SetRect(&rc
, 20, 20, 80, 80);
51 IntersectClipRect(hdc
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
53 ret
= GetRandomRgn(hdc
, hrgn
, 1);
54 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
55 GetRgnBox(hrgn
, &ret_rc
);
56 ok(EqualRect(&rc
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
57 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
59 ret
= GetRandomRgn(hdc
, hrgn
, 2);
60 ok(ret
== 0, "GetRandomRgn rets %d\n", ret
);
62 ret
= GetRandomRgn(hdc
, hrgn
, 3);
63 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
64 GetRgnBox(hrgn
, &ret_rc
);
65 ok(EqualRect(&rc
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
66 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
68 /* Move the clip to the meta and clear the clip */
71 ret
= GetRandomRgn(hdc
, hrgn
, 1);
72 ok(ret
== 0, "GetRandomRgn rets %d\n", ret
);
73 ret
= GetRandomRgn(hdc
, hrgn
, 2);
74 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
75 GetRgnBox(hrgn
, &ret_rc
);
76 ok(EqualRect(&rc
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
77 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
79 ret
= GetRandomRgn(hdc
, hrgn
, 3);
80 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
81 GetRgnBox(hrgn
, &ret_rc
);
82 ok(EqualRect(&rc
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
83 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
85 /* Set a new clip (still got the meta) */
86 SetRect(&rc2
, 10, 30, 70, 90);
87 IntersectClipRect(hdc
, rc2
.left
, rc2
.top
, rc2
.right
, rc2
.bottom
);
89 ret
= GetRandomRgn(hdc
, hrgn
, 1);
90 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
91 GetRgnBox(hrgn
, &ret_rc
);
92 ok(EqualRect(&rc2
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
93 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
95 ret
= GetRandomRgn(hdc
, hrgn
, 2);
96 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
97 GetRgnBox(hrgn
, &ret_rc
);
98 ok(EqualRect(&rc
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
99 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
101 IntersectRect(&rc2
, &rc
, &rc2
);
103 ret
= GetRandomRgn(hdc
, hrgn
, 3);
104 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
105 GetRgnBox(hrgn
, &ret_rc
);
106 ok(EqualRect(&rc2
, &ret_rc
), "GetRandomRgn %d,%d - %d,%d\n",
107 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
110 ret
= GetRandomRgn(hdc
, hrgn
, SYSRGN
);
111 ok(ret
!= 0, "GetRandomRgn rets %d\n", ret
);
112 GetRgnBox(hrgn
, &ret_rc
);
113 if(GetVersion() & 0x80000000)
114 OffsetRect(&window_rc
, -window_rc
.left
, -window_rc
.top
);
115 ok(EqualRect(&window_rc
, &ret_rc
) ||
116 broken(IsRectEmpty(&ret_rc
)), /* win95 */
117 "GetRandomRgn %d,%d - %d,%d\n",
118 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
121 ReleaseDC(hwnd
, hdc
);
125 static void verify_region(HRGN hrgn
, const RECT
*rc
)
130 char buf
[sizeof(RGNDATAHEADER
) + sizeof(RECT
)];
135 ret
= GetRegionData(hrgn
, 0, NULL
);
137 ok(ret
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", ret
);
139 ok(ret
== sizeof(rgn
.data
.rdh
) + sizeof(RECT
), "expected sizeof(rgn), got %u\n", ret
);
143 ret
= GetRegionData(hrgn
, sizeof(rgn
), &rgn
.data
);
145 ok(ret
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", ret
);
147 ok(ret
== sizeof(rgn
.data
.rdh
) + sizeof(RECT
), "expected sizeof(rgn), got %u\n", ret
);
149 trace("size %u, type %u, count %u, rgn size %u, bound (%d,%d-%d,%d)\n",
150 rgn
.data
.rdh
.dwSize
, rgn
.data
.rdh
.iType
,
151 rgn
.data
.rdh
.nCount
, rgn
.data
.rdh
.nRgnSize
,
152 rgn
.data
.rdh
.rcBound
.left
, rgn
.data
.rdh
.rcBound
.top
,
153 rgn
.data
.rdh
.rcBound
.right
, rgn
.data
.rdh
.rcBound
.bottom
);
154 if (rgn
.data
.rdh
.nCount
!= 0)
156 rect
= (const RECT
*)rgn
.data
.Buffer
;
157 trace("rect (%d,%d-%d,%d)\n", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
158 ok(EqualRect(rect
, rc
), "rects don't match\n");
161 ok(rgn
.data
.rdh
.dwSize
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", rgn
.data
.rdh
.dwSize
);
162 ok(rgn
.data
.rdh
.iType
== RDH_RECTANGLES
, "expected RDH_RECTANGLES, got %u\n", rgn
.data
.rdh
.iType
);
165 ok(rgn
.data
.rdh
.nCount
== 0, "expected 0, got %u\n", rgn
.data
.rdh
.nCount
);
166 ok(rgn
.data
.rdh
.nRgnSize
== 0 ||
167 broken(rgn
.data
.rdh
.nRgnSize
== 168), /* NT4 */
168 "expected 0, got %u\n", rgn
.data
.rdh
.nRgnSize
);
172 ok(rgn
.data
.rdh
.nCount
== 1, "expected 1, got %u\n", rgn
.data
.rdh
.nCount
);
173 ok(rgn
.data
.rdh
.nRgnSize
== sizeof(RECT
) ||
174 broken(rgn
.data
.rdh
.nRgnSize
== 168), /* NT4 */
175 "expected sizeof(RECT), got %u\n", rgn
.data
.rdh
.nRgnSize
);
177 ok(EqualRect(&rgn
.data
.rdh
.rcBound
, rc
), "rects don't match\n");
180 static void test_ExtCreateRegion(void)
182 static const RECT empty_rect
;
183 static const RECT rc
= { 111, 222, 333, 444 };
184 static const RECT rc_xformed
= { 76, 151, 187, 262 };
188 char buf
[sizeof(RGNDATAHEADER
) + sizeof(RECT
)];
193 if (0) /* crashes under Win9x */
195 SetLastError(0xdeadbeef);
196 hrgn
= ExtCreateRegion(NULL
, 0, NULL
);
197 ok(!hrgn
, "ExtCreateRegion should fail\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
201 rgn
.data
.rdh
.dwSize
= 0;
202 rgn
.data
.rdh
.iType
= 0;
203 rgn
.data
.rdh
.nCount
= 0;
204 rgn
.data
.rdh
.nRgnSize
= 0;
205 SetRectEmpty(&rgn
.data
.rdh
.rcBound
);
206 memcpy(rgn
.data
.Buffer
, &rc
, sizeof(rc
));
208 SetLastError(0xdeadbeef);
209 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
210 ok(!hrgn
, "ExtCreateRegion should fail\n");
211 ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
213 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
) - 1;
215 SetLastError(0xdeadbeef);
216 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
217 ok(!hrgn
, "ExtCreateRegion should fail\n");
218 ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
220 /* although XP doesn't care about the type Win9x does */
221 rgn
.data
.rdh
.iType
= RDH_RECTANGLES
;
222 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
);
224 SetLastError(0xdeadbeef);
225 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
226 ok(hrgn
!= 0, "ExtCreateRegion error %u\n", GetLastError());
227 verify_region(hrgn
, &empty_rect
);
230 rgn
.data
.rdh
.nCount
= 1;
231 SetRectEmpty(&rgn
.data
.rdh
.rcBound
);
232 memcpy(rgn
.data
.Buffer
, &rc
, sizeof(rc
));
234 SetLastError(0xdeadbeef);
235 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
236 ok(hrgn
!= 0, "ExtCreateRegion error %u\n", GetLastError());
237 verify_region(hrgn
, &rc
);
240 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
) + 1;
242 SetLastError(0xdeadbeef);
243 hrgn
= ExtCreateRegion(NULL
, 1, &rgn
.data
);
245 broken(GetLastError() == 0xdeadbeef), /* NT4 */
246 "ExtCreateRegion error %u\n", GetLastError());
249 verify_region(hrgn
, &rc
);
253 xform
.eM11
= 0.5; /* 50% width */
256 xform
.eM22
= 0.5; /* 50% height */
260 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
);
262 SetLastError(0xdeadbeef);
263 hrgn
= ExtCreateRegion(&xform
, sizeof(rgn
), &rgn
.data
);
264 ok(hrgn
!= 0, "ExtCreateRegion error %u/%x\n", GetLastError(), GetLastError());
265 verify_region(hrgn
, &rc_xformed
);
269 static void test_GetClipRgn(void)
272 HRGN hrgn
, hrgn2
, hrgn3
, hrgn4
;
275 /* Test calling GetClipRgn with NULL device context and region handles. */
276 ret
= GetClipRgn(NULL
, NULL
);
277 ok(ret
== -1, "Expected GetClipRgn to return -1, got %d\n", ret
);
280 ok(hdc
!= NULL
, "Expected GetDC to return a valid device context handle\n");
282 /* Test calling GetClipRgn with a valid device context and NULL region. */
283 ret
= GetClipRgn(hdc
, NULL
);
285 ret
== -1 /* Win9x */,
286 "Expected GetClipRgn to return 0, got %d\n", ret
);
288 /* Initialize the test regions. */
289 hrgn
= CreateRectRgn(100, 100, 100, 100);
291 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
293 hrgn2
= CreateRectRgn(1, 2, 3, 4);
295 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
297 hrgn3
= CreateRectRgn(1, 2, 3, 4);
299 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
301 hrgn4
= CreateRectRgn(1, 2, 3, 4);
303 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
305 /* Try getting a clipping region from the device context
306 * when the device context's clipping region isn't set. */
307 ret
= GetClipRgn(hdc
, hrgn2
);
308 ok(ret
== 0, "Expected GetClipRgn to return 0, got %d\n", ret
);
310 /* The region passed to GetClipRgn should be unchanged. */
311 ret
= EqualRgn(hrgn2
, hrgn3
);
313 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
315 /* Try setting and getting back a clipping region. */
316 ret
= SelectClipRgn(hdc
, hrgn
);
317 ok(ret
== NULLREGION
,
318 "Expected SelectClipRgn to return NULLREGION, got %d\n", ret
);
320 /* Passing a NULL region handle when the device context
321 * has a clipping region results in an error. */
322 ret
= GetClipRgn(hdc
, NULL
);
323 ok(ret
== -1, "Expected GetClipRgn to return -1, got %d\n", ret
);
325 ret
= GetClipRgn(hdc
, hrgn2
);
326 ok(ret
== 1, "Expected GetClipRgn to return 1, got %d\n", ret
);
328 ret
= EqualRgn(hrgn
, hrgn2
);
330 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
332 /* Try unsetting and then query the clipping region. */
333 ret
= SelectClipRgn(hdc
, NULL
);
334 ok(ret
== SIMPLEREGION
,
335 "Expected SelectClipRgn to return SIMPLEREGION, got %d\n", ret
);
337 ret
= GetClipRgn(hdc
, NULL
);
339 ret
== -1 /* Win9x */,
340 "Expected GetClipRgn to return 0, got %d\n", ret
);
342 ret
= GetClipRgn(hdc
, hrgn3
);
343 ok(ret
== 0, "Expected GetClipRgn to return 0, got %d\n", ret
);
345 ret
= EqualRgn(hrgn3
, hrgn4
);
347 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
353 ReleaseDC(NULL
, hdc
);
356 static void test_memory_dc_clipping(void)
359 HRGN hrgn
, hrgn_empty
;
364 hdc
= CreateCompatibleDC(0);
365 hrgn_empty
= CreateRectRgn(0, 0, 0, 0);
366 hrgn
= CreateRectRgn(0, 0, 0, 0);
367 hbmp
= CreateCompatibleBitmap(hdc
, 100, 100);
369 ret
= GetClipRgn(hdc
, hrgn
);
370 ok(ret
== 0, "expected 0, got %d\n", ret
);
372 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
373 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
375 ret
= GetClipRgn(hdc
, hrgn
);
376 ok(ret
== 1, "expected 1, got %d\n", ret
);
378 ret
= GetRgnBox(hrgn
, &rc
);
379 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
380 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== 1 && rc
.bottom
== 1,
381 "expected 0,0-1,1, got %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
383 ret
= ExtSelectClipRgn(hdc
, 0, RGN_COPY
);
384 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
386 ret
= GetClipRgn(hdc
, hrgn
);
387 ok(ret
== 0, "expected 0, got %d\n", ret
);
389 SelectObject(hdc
, hbmp
);
391 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
392 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
394 ret
= GetClipRgn(hdc
, hrgn
);
395 ok(ret
== 1, "expected 1, got %d\n", ret
);
397 ret
= GetRgnBox(hrgn
, &rc
);
398 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
399 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== 100 && rc
.bottom
== 100,
400 "expected 0,0-100,100, got %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
404 DeleteObject(hrgn_empty
);
408 static void test_window_dc_clipping(void)
411 HRGN hrgn
, hrgn_empty
;
414 int ret
, screen_width
, screen_height
;
416 /* Windows versions earlier than Win2k do not support the virtual screen metrics,
417 * so we fall back to the primary screen metrics. */
418 screen_width
= GetSystemMetrics(SM_CXVIRTUALSCREEN
);
419 if(!screen_width
) screen_width
= GetSystemMetrics(SM_CXSCREEN
);
420 screen_height
= GetSystemMetrics(SM_CYVIRTUALSCREEN
);
421 if(!screen_height
) screen_height
= GetSystemMetrics(SM_CYSCREEN
);
423 trace("screen resolution %d x %d\n", screen_width
, screen_height
);
425 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
426 -100, -100, screen_width
* 2, screen_height
* 2, 0, 0, 0, NULL
);
427 hdc
= GetWindowDC(0);
428 hrgn_empty
= CreateRectRgn(0, 0, 0, 0);
429 hrgn
= CreateRectRgn(0, 0, 0, 0);
431 ret
= GetClipRgn(hdc
, hrgn
);
432 ok(ret
== 0, "expected 0, got %d\n", ret
);
434 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
435 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
437 ret
= GetClipRgn(hdc
, hrgn
);
438 ok(ret
== 1, "expected 1, got %d\n", ret
);
440 ret
= GetRgnBox(hrgn
, &rc
);
441 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
442 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== screen_width
&& rc
.bottom
== screen_height
,
443 "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width
, screen_height
,
444 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
446 ret
= ExtSelectClipRgn(hdc
, 0, RGN_COPY
);
447 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
449 ret
= GetClipRgn(hdc
, hrgn
);
450 ok(ret
== 0, "expected 0, got %d\n", ret
);
454 DeleteObject(hrgn_empty
);
462 test_ExtCreateRegion();
464 test_memory_dc_clipping();
465 test_window_dc_clipping();