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 /* the window may be partially obscured so the region may be smaller */
116 IntersectRect( &window_rc
, &ret_rc
, &ret_rc
);
117 ok(EqualRect(&window_rc
, &ret_rc
) ||
118 broken(IsRectEmpty(&ret_rc
)), /* win95 */
119 "GetRandomRgn %d,%d - %d,%d\n",
120 ret_rc
.left
, ret_rc
.top
, ret_rc
.right
, ret_rc
.bottom
);
123 ReleaseDC(hwnd
, hdc
);
127 static void verify_region(HRGN hrgn
, const RECT
*rc
)
132 char buf
[sizeof(RGNDATAHEADER
) + sizeof(RECT
)];
137 ret
= GetRegionData(hrgn
, 0, NULL
);
139 ok(ret
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", ret
);
141 ok(ret
== sizeof(rgn
.data
.rdh
) + sizeof(RECT
), "expected sizeof(rgn), got %u\n", ret
);
145 ret
= GetRegionData(hrgn
, sizeof(rgn
), &rgn
.data
);
147 ok(ret
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", ret
);
149 ok(ret
== sizeof(rgn
.data
.rdh
) + sizeof(RECT
), "expected sizeof(rgn), got %u\n", ret
);
151 trace("size %u, type %u, count %u, rgn size %u, bound (%d,%d-%d,%d)\n",
152 rgn
.data
.rdh
.dwSize
, rgn
.data
.rdh
.iType
,
153 rgn
.data
.rdh
.nCount
, rgn
.data
.rdh
.nRgnSize
,
154 rgn
.data
.rdh
.rcBound
.left
, rgn
.data
.rdh
.rcBound
.top
,
155 rgn
.data
.rdh
.rcBound
.right
, rgn
.data
.rdh
.rcBound
.bottom
);
156 if (rgn
.data
.rdh
.nCount
!= 0)
158 rect
= (const RECT
*)rgn
.data
.Buffer
;
159 trace("rect (%d,%d-%d,%d)\n", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
160 ok(EqualRect(rect
, rc
), "rects don't match\n");
163 ok(rgn
.data
.rdh
.dwSize
== sizeof(rgn
.data
.rdh
), "expected sizeof(rdh), got %u\n", rgn
.data
.rdh
.dwSize
);
164 ok(rgn
.data
.rdh
.iType
== RDH_RECTANGLES
, "expected RDH_RECTANGLES, got %u\n", rgn
.data
.rdh
.iType
);
167 ok(rgn
.data
.rdh
.nCount
== 0, "expected 0, got %u\n", rgn
.data
.rdh
.nCount
);
168 ok(rgn
.data
.rdh
.nRgnSize
== 0 ||
169 broken(rgn
.data
.rdh
.nRgnSize
== 168), /* NT4 */
170 "expected 0, got %u\n", rgn
.data
.rdh
.nRgnSize
);
174 ok(rgn
.data
.rdh
.nCount
== 1, "expected 1, got %u\n", rgn
.data
.rdh
.nCount
);
175 ok(rgn
.data
.rdh
.nRgnSize
== sizeof(RECT
) ||
176 broken(rgn
.data
.rdh
.nRgnSize
== 168), /* NT4 */
177 "expected sizeof(RECT), got %u\n", rgn
.data
.rdh
.nRgnSize
);
179 ok(EqualRect(&rgn
.data
.rdh
.rcBound
, rc
), "rects don't match\n");
182 static void test_ExtCreateRegion(void)
184 static const RECT empty_rect
;
185 static const RECT rc
= { 111, 222, 333, 444 };
186 static const RECT rc_xformed
= { 76, 151, 187, 262 };
190 char buf
[sizeof(RGNDATAHEADER
) + sizeof(RECT
)];
195 if (0) /* crashes under Win9x */
197 SetLastError(0xdeadbeef);
198 hrgn
= ExtCreateRegion(NULL
, 0, NULL
);
199 ok(!hrgn
, "ExtCreateRegion should fail\n");
200 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
203 rgn
.data
.rdh
.dwSize
= 0;
204 rgn
.data
.rdh
.iType
= 0;
205 rgn
.data
.rdh
.nCount
= 0;
206 rgn
.data
.rdh
.nRgnSize
= 0;
207 SetRectEmpty(&rgn
.data
.rdh
.rcBound
);
208 memcpy(rgn
.data
.Buffer
, &rc
, sizeof(rc
));
210 SetLastError(0xdeadbeef);
211 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
212 ok(!hrgn
, "ExtCreateRegion should fail\n");
213 ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
215 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
) - 1;
217 SetLastError(0xdeadbeef);
218 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
219 ok(!hrgn
, "ExtCreateRegion should fail\n");
220 ok(GetLastError() == 0xdeadbeef, "0xdeadbeef, got %u\n", GetLastError());
222 /* although XP doesn't care about the type Win9x does */
223 rgn
.data
.rdh
.iType
= RDH_RECTANGLES
;
224 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
);
226 SetLastError(0xdeadbeef);
227 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
228 ok(hrgn
!= 0, "ExtCreateRegion error %u\n", GetLastError());
229 verify_region(hrgn
, &empty_rect
);
232 rgn
.data
.rdh
.nCount
= 1;
233 SetRectEmpty(&rgn
.data
.rdh
.rcBound
);
234 memcpy(rgn
.data
.Buffer
, &rc
, sizeof(rc
));
236 SetLastError(0xdeadbeef);
237 hrgn
= ExtCreateRegion(NULL
, sizeof(rgn
), &rgn
.data
);
238 ok(hrgn
!= 0, "ExtCreateRegion error %u\n", GetLastError());
239 verify_region(hrgn
, &rc
);
242 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
) + 1;
244 SetLastError(0xdeadbeef);
245 hrgn
= ExtCreateRegion(NULL
, 1, &rgn
.data
);
247 broken(GetLastError() == 0xdeadbeef), /* NT4 */
248 "ExtCreateRegion error %u\n", GetLastError());
251 verify_region(hrgn
, &rc
);
255 xform
.eM11
= 0.5; /* 50% width */
258 xform
.eM22
= 0.5; /* 50% height */
262 rgn
.data
.rdh
.dwSize
= sizeof(rgn
.data
.rdh
);
264 SetLastError(0xdeadbeef);
265 hrgn
= ExtCreateRegion(&xform
, sizeof(rgn
), &rgn
.data
);
266 ok(hrgn
!= 0, "ExtCreateRegion error %u/%x\n", GetLastError(), GetLastError());
267 verify_region(hrgn
, &rc_xformed
);
271 static void test_GetClipRgn(void)
274 HRGN hrgn
, hrgn2
, hrgn3
, hrgn4
;
277 /* Test calling GetClipRgn with NULL device context and region handles. */
278 ret
= GetClipRgn(NULL
, NULL
);
279 ok(ret
== -1, "Expected GetClipRgn to return -1, got %d\n", ret
);
282 ok(hdc
!= NULL
, "Expected GetDC to return a valid device context handle\n");
284 /* Test calling GetClipRgn with a valid device context and NULL region. */
285 ret
= GetClipRgn(hdc
, NULL
);
287 ret
== -1 /* Win9x */,
288 "Expected GetClipRgn to return 0, got %d\n", ret
);
290 /* Initialize the test regions. */
291 hrgn
= CreateRectRgn(100, 100, 100, 100);
293 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
295 hrgn2
= CreateRectRgn(1, 2, 3, 4);
297 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
299 hrgn3
= CreateRectRgn(1, 2, 3, 4);
301 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
303 hrgn4
= CreateRectRgn(1, 2, 3, 4);
305 "Expected CreateRectRgn to return a handle to a new rectangular region\n");
307 /* Try getting a clipping region from the device context
308 * when the device context's clipping region isn't set. */
309 ret
= GetClipRgn(hdc
, hrgn2
);
310 ok(ret
== 0, "Expected GetClipRgn to return 0, got %d\n", ret
);
312 /* The region passed to GetClipRgn should be unchanged. */
313 ret
= EqualRgn(hrgn2
, hrgn3
);
315 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
317 /* Try setting and getting back a clipping region. */
318 ret
= SelectClipRgn(hdc
, hrgn
);
319 ok(ret
== NULLREGION
,
320 "Expected SelectClipRgn to return NULLREGION, got %d\n", ret
);
322 /* Passing a NULL region handle when the device context
323 * has a clipping region results in an error. */
324 ret
= GetClipRgn(hdc
, NULL
);
325 ok(ret
== -1, "Expected GetClipRgn to return -1, got %d\n", ret
);
327 ret
= GetClipRgn(hdc
, hrgn2
);
328 ok(ret
== 1, "Expected GetClipRgn to return 1, got %d\n", ret
);
330 ret
= EqualRgn(hrgn
, hrgn2
);
332 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
334 /* Try unsetting and then query the clipping region. */
335 ret
= SelectClipRgn(hdc
, NULL
);
336 ok(ret
== SIMPLEREGION
|| (ret
== COMPLEXREGION
&& GetSystemMetrics(SM_CMONITORS
) > 1),
337 "Expected SelectClipRgn to return SIMPLEREGION, got %d\n", ret
);
339 ret
= GetClipRgn(hdc
, NULL
);
341 ret
== -1 /* Win9x */,
342 "Expected GetClipRgn to return 0, got %d\n", ret
);
344 ret
= GetClipRgn(hdc
, hrgn3
);
345 ok(ret
== 0, "Expected GetClipRgn to return 0, got %d\n", ret
);
347 ret
= EqualRgn(hrgn3
, hrgn4
);
349 "Expected EqualRgn to compare the two regions as equal, got %d\n", ret
);
355 ReleaseDC(NULL
, hdc
);
358 static void test_memory_dc_clipping(void)
361 HRGN hrgn
, hrgn_empty
;
366 hdc
= CreateCompatibleDC(0);
367 hrgn_empty
= CreateRectRgn(0, 0, 0, 0);
368 hrgn
= CreateRectRgn(0, 0, 0, 0);
369 hbmp
= CreateCompatibleBitmap(hdc
, 100, 100);
371 ret
= GetClipRgn(hdc
, hrgn
);
372 ok(ret
== 0, "expected 0, got %d\n", ret
);
374 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
375 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
377 ret
= GetClipRgn(hdc
, hrgn
);
378 ok(ret
== 1, "expected 1, got %d\n", ret
);
380 ret
= GetRgnBox(hrgn
, &rc
);
381 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
382 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== 1 && rc
.bottom
== 1,
383 "expected 0,0-1,1, got %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
385 ret
= ExtSelectClipRgn(hdc
, 0, RGN_COPY
);
386 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
388 ret
= GetClipRgn(hdc
, hrgn
);
389 ok(ret
== 0, "expected 0, got %d\n", ret
);
391 SelectObject(hdc
, hbmp
);
393 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
394 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
396 ret
= GetClipRgn(hdc
, hrgn
);
397 ok(ret
== 1, "expected 1, got %d\n", ret
);
399 ret
= GetRgnBox(hrgn
, &rc
);
400 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
401 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== 100 && rc
.bottom
== 100,
402 "expected 0,0-100,100, got %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
404 SetRect( &rc
, 10, 10, 20, 20 );
405 ret
= RectVisible( hdc
, &rc
);
406 ok( ret
, "RectVisible failed for %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
408 SetRect( &rc
, 20, 20, 10, 10 );
409 ret
= RectVisible( hdc
, &rc
);
410 ok( ret
, "RectVisible failed for %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
414 DeleteObject(hrgn_empty
);
418 static void test_window_dc_clipping(void)
421 HRGN hrgn
, hrgn_empty
;
424 int ret
, screen_width
, screen_height
;
426 /* Windows versions earlier than Win2k do not support the virtual screen metrics,
427 * so we fall back to the primary screen metrics. */
428 screen_width
= GetSystemMetrics(SM_CXVIRTUALSCREEN
);
429 if(!screen_width
) screen_width
= GetSystemMetrics(SM_CXSCREEN
);
430 screen_height
= GetSystemMetrics(SM_CYVIRTUALSCREEN
);
431 if(!screen_height
) screen_height
= GetSystemMetrics(SM_CYSCREEN
);
433 trace("screen resolution %d x %d\n", screen_width
, screen_height
);
435 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
,
436 -100, -100, screen_width
* 2, screen_height
* 2, 0, 0, 0, NULL
);
437 hdc
= GetWindowDC(0);
438 hrgn_empty
= CreateRectRgn(0, 0, 0, 0);
439 hrgn
= CreateRectRgn(0, 0, 0, 0);
441 ret
= GetClipRgn(hdc
, hrgn
);
442 ok(ret
== 0, "expected 0, got %d\n", ret
);
444 ret
= ExtSelectClipRgn(hdc
, hrgn_empty
, RGN_DIFF
);
445 ok(ret
== SIMPLEREGION
|| (ret
== COMPLEXREGION
&& GetSystemMetrics(SM_CMONITORS
) > 1),
446 "expected SIMPLEREGION, got %d\n", ret
);
448 ret
= GetClipRgn(hdc
, hrgn
);
449 ok(ret
== 1, "expected 1, got %d\n", ret
);
451 ret
= GetRgnBox(hrgn
, &rc
);
452 ok(ret
== SIMPLEREGION
, "expected SIMPLEREGION, got %d\n", ret
);
453 ok(rc
.left
== 0 && rc
.top
== 0 && rc
.right
== screen_width
&& rc
.bottom
== screen_height
,
454 "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width
, screen_height
,
455 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
457 SetRect( &rc
, 10, 10, 20, 20 );
458 ret
= RectVisible( hdc
, &rc
);
459 ok( ret
, "RectVisible failed for %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
461 SetRect( &rc
, 20, 20, 10, 10 );
462 ret
= RectVisible( hdc
, &rc
);
463 ok( ret
, "RectVisible failed for %d,%d-%d,%d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
465 ret
= ExtSelectClipRgn(hdc
, 0, RGN_COPY
);
466 ok(ret
== SIMPLEREGION
|| (ret
== COMPLEXREGION
&& GetSystemMetrics(SM_CMONITORS
) > 1),
467 "expected SIMPLEREGION, got %d\n", ret
);
469 ret
= GetClipRgn(hdc
, hrgn
);
470 ok(ret
== 0, "expected 0, got %d\n", ret
);
474 DeleteObject(hrgn_empty
);
482 test_ExtCreateRegion();
484 test_memory_dc_clipping();
485 test_window_dc_clipping();