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();