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,
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);
406 DeleteObject(hrgn_empty);
410 static void test_window_dc_clipping(void)
413 HRGN hrgn, hrgn_empty;
416 int ret, screen_width, screen_height;
418 /* Windows versions earlier than Win2k do not support the virtual screen metrics,
419 * so we fall back to the primary screen metrics. */
420 screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
421 if(!screen_width) screen_width = GetSystemMetrics(SM_CXSCREEN);
422 screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
423 if(!screen_height) screen_height = GetSystemMetrics(SM_CYSCREEN);
425 trace("screen resolution %d x %d\n", screen_width, screen_height);
427 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
428 -100, -100, screen_width * 2, screen_height * 2, 0, 0, 0, NULL);
429 hdc = GetWindowDC(0);
430 hrgn_empty = CreateRectRgn(0, 0, 0, 0);
431 hrgn = CreateRectRgn(0, 0, 0, 0);
433 ret = GetClipRgn(hdc, hrgn);
434 ok(ret == 0, "expected 0, got %d\n", ret);
436 ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
437 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
439 ret = GetClipRgn(hdc, hrgn);
440 ok(ret == 1, "expected 1, got %d\n", ret);
442 ret = GetRgnBox(hrgn, &rc);
443 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
444 ok(rc.left == 0 && rc.top == 0 && rc.right == screen_width && rc.bottom == screen_height,
445 "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width, screen_height,
446 rc.left, rc.top, rc.right, rc.bottom);
448 ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
449 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
451 ret = GetClipRgn(hdc, hrgn);
452 ok(ret == 0, "expected 0, got %d\n", ret);
456 DeleteObject(hrgn_empty);
464 test_ExtCreateRegion();
466 test_memory_dc_clipping();
467 test_window_dc_clipping();