[GDIPLUS_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / gdiplus / region.c
1 /*
2 * Unit test suite for gdiplus regions
3 *
4 * Copyright (C) 2008 Huw Davies
5 * Copyright (C) 2013 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "precomp.h"
23
24 #define RGNDATA_RECT 0x10000000
25 #define RGNDATA_PATH 0x10000001
26 #define RGNDATA_EMPTY_RECT 0x10000002
27 #define RGNDATA_INFINITE_RECT 0x10000003
28
29 #define RGNDATA_MAGIC 0xdbc01001
30 #define RGNDATA_MAGIC2 0xdbc01002
31
32 #define expect(expected, got) ok((got) == (expected), "Expected %.8x, got %.8x\n", (expected), (got))
33 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) < (precision), "Expected %f, got %f\n", (expected), (got))
34 #define expectf(expected, got) expectf_((expected), (got), 0.001)
35
36 #define expect_magic(value) ok(broken(*(value) == RGNDATA_MAGIC) || *(value) == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *(value))
37 #define expect_dword(value, expected) expect((expected), *(value))
38 #define expect_float(value, expected) expectf((expected), *(FLOAT *)(value))
39
40 /* We get shorts back, not INTs like a GpPoint */
41 typedef struct RegionDataPoint
42 {
43 short X, Y;
44 } RegionDataPoint;
45
46 static void verify_region(HRGN hrgn, const RECT *rc)
47 {
48 union
49 {
50 RGNDATA data;
51 char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
52 } rgn;
53 const RECT *rect;
54 DWORD ret;
55
56 ret = GetRegionData(hrgn, 0, NULL);
57 if (IsRectEmpty(rc))
58 ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
59 else
60 ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
61
62 if (!ret) return;
63
64 ret = GetRegionData(hrgn, sizeof(rgn), &rgn.data);
65 if (IsRectEmpty(rc))
66 ok(ret == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", ret);
67 else
68 ok(ret == sizeof(rgn.data.rdh) + sizeof(RECT), "expected sizeof(rgn), got %u\n", ret);
69
70 trace("size %u, type %u, count %u, rgn size %u, bound %s\n",
71 rgn.data.rdh.dwSize, rgn.data.rdh.iType,
72 rgn.data.rdh.nCount, rgn.data.rdh.nRgnSize,
73 wine_dbgstr_rect(&rgn.data.rdh.rcBound));
74 if (rgn.data.rdh.nCount != 0)
75 {
76 rect = (const RECT *)rgn.data.Buffer;
77 trace("rect %s\n", wine_dbgstr_rect(rect));
78 ok(EqualRect(rect, rc), "expected %s, got %s\n",
79 wine_dbgstr_rect(rc), wine_dbgstr_rect(rect));
80 }
81
82 ok(rgn.data.rdh.dwSize == sizeof(rgn.data.rdh), "expected sizeof(rdh), got %u\n", rgn.data.rdh.dwSize);
83 ok(rgn.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn.data.rdh.iType);
84 if (IsRectEmpty(rc))
85 {
86 ok(rgn.data.rdh.nCount == 0, "expected 0, got %u\n", rgn.data.rdh.nCount);
87 ok(rgn.data.rdh.nRgnSize == 0, "expected 0, got %u\n", rgn.data.rdh.nRgnSize);
88 }
89 else
90 {
91 ok(rgn.data.rdh.nCount == 1, "expected 1, got %u\n", rgn.data.rdh.nCount);
92 ok(rgn.data.rdh.nRgnSize == sizeof(RECT), "expected sizeof(RECT), got %u\n", rgn.data.rdh.nRgnSize);
93 }
94 ok(EqualRect(&rgn.data.rdh.rcBound, rc), "expected %s, got %s\n",
95 wine_dbgstr_rect(rc), wine_dbgstr_rect(&rgn.data.rdh.rcBound));
96 }
97
98 static void test_region_data(DWORD *data, UINT size, INT line)
99 {
100 GpStatus status;
101 GpRegion *region;
102 DWORD buf[256];
103 UINT needed, i;
104
105 status = GdipCreateRegionRgnData((BYTE *)data, size, &region);
106 /* Windows always fails to create an empty path in a region */
107 if (data[4] == RGNDATA_PATH)
108 {
109 struct path_header
110 {
111 DWORD size;
112 DWORD magic;
113 DWORD count;
114 DWORD flags;
115 } *path_header = (struct path_header *)(data + 5);
116 if (!path_header->count)
117 {
118 ok_(__FILE__, line)(status == GenericError, "expected GenericError, got %d\n", status);
119 return;
120 }
121 }
122
123 ok_(__FILE__, line)(status == Ok, "GdipCreateRegionRgnData error %d\n", status);
124 if (status != Ok) return;
125
126 needed = 0;
127 status = GdipGetRegionDataSize(region, &needed);
128 ok_(__FILE__, line)(status == Ok, "status %d\n", status);
129 ok_(__FILE__, line)(needed == size, "data size mismatch: %u != %u\n", needed, size);
130
131 memset(buf, 0xee, sizeof(buf));
132 needed = 0;
133 status = GdipGetRegionData(region, (BYTE *)buf, sizeof(buf), &needed);
134 ok_(__FILE__, line)(status == Ok, "status %08x\n", status);
135 ok_(__FILE__, line)(needed == size, "data size mismatch: %u != %u\n", needed, size);
136
137 size /= sizeof(DWORD);
138 for (i = 0; i < size - 1; i++)
139 {
140 if (i == 1) continue; /* data[1] never matches */
141 ok_(__FILE__, line)(data[i] == buf[i], "off %u: %#x != %#x\n", i, data[i], buf[i]);
142 }
143 /* some Windows versions fail to properly clear the aligned DWORD */
144 ok_(__FILE__, line)(data[size - 1] == buf[size - 1] || broken(data[size - 1] != buf[size - 1]),
145 "off %u: %#x != %#x\n", size - 1, data[size - 1], buf[size - 1]);
146
147 GdipDeleteRegion(region);
148 }
149
150 static void test_getregiondata(void)
151 {
152 GpStatus status;
153 GpRegion *region, *region2;
154 RegionDataPoint *point;
155 UINT needed;
156 DWORD buf[256];
157 GpRect rect;
158 GpPath *path;
159 GpMatrix *matrix;
160
161 status = GdipCreateRegion(&region);
162 ok(status == Ok, "status %08x\n", status);
163
164 needed = 0;
165 status = GdipGetRegionDataSize(region, &needed);
166 ok(status == Ok, "status %08x\n", status);
167 expect(20, needed);
168
169 needed = 0;
170 status = GdipGetRegionData(region, (BYTE*)buf, 0, &needed);
171 ok(status == InvalidParameter, "status %08x\n", status);
172
173 memset(buf, 0xee, sizeof(buf));
174 needed = 0;
175 status = GdipGetRegionData(region, (BYTE*)buf, 4, &needed);
176 ok(status == InsufficientBuffer, "status %08x\n", status);
177 expect(4, needed);
178 expect_dword(buf, 0xeeeeeeee);
179
180 memset(buf, 0xee, sizeof(buf));
181 needed = 0;
182 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
183 ok(status == Ok, "status %08x\n", status);
184 expect(20, needed);
185 expect_dword(buf, 12);
186 trace("buf[1] = %08x\n", buf[1]);
187 expect_magic(buf + 2);
188 expect_dword(buf + 3, 0);
189 expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
190 expect_dword(buf + 6, 0xeeeeeeee);
191 test_region_data(buf, needed, __LINE__);
192
193 status = GdipSetEmpty(region);
194 ok(status == Ok, "status %08x\n", status);
195 status = GdipGetRegionDataSize(region, &needed);
196 ok(status == Ok, "status %08x\n", status);
197 expect(20, needed);
198 memset(buf, 0xee, sizeof(buf));
199 needed = 0;
200 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
201 ok(status == Ok, "status %08x\n", status);
202 expect(20, needed);
203 expect_dword(buf, 12);
204 trace("buf[1] = %08x\n", buf[1]);
205 expect_magic(buf + 2);
206 expect_dword(buf + 3, 0);
207 expect_dword(buf + 4, RGNDATA_EMPTY_RECT);
208 expect_dword(buf + 6, 0xeeeeeeee);
209 test_region_data(buf, needed, __LINE__);
210
211 status = GdipSetInfinite(region);
212 ok(status == Ok, "status %08x\n", status);
213 status = GdipGetRegionDataSize(region, &needed);
214 ok(status == Ok, "status %08x\n", status);
215 expect(20, needed);
216 memset(buf, 0xee, sizeof(buf));
217 needed = 0;
218 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
219 ok(status == Ok, "status %08x\n", status);
220 expect(20, needed);
221 expect_dword(buf, 12);
222 trace("buf[1] = %08x\n", buf[1]);
223 expect_magic(buf + 2);
224 expect_dword(buf + 3, 0);
225 expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
226 expect_dword(buf + 6, 0xeeeeeeee);
227 test_region_data(buf, needed, __LINE__);
228
229 status = GdipDeleteRegion(region);
230 ok(status == Ok, "status %08x\n", status);
231
232 rect.X = 10;
233 rect.Y = 20;
234 rect.Width = 100;
235 rect.Height = 200;
236 status = GdipCreateRegionRectI(&rect, &region);
237 ok(status == Ok, "status %08x\n", status);
238 status = GdipGetRegionDataSize(region, &needed);
239 ok(status == Ok, "status %08x\n", status);
240 expect(36, needed);
241 memset(buf, 0xee, sizeof(buf));
242 needed = 0;
243 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
244 ok(status == Ok, "status %08x\n", status);
245 expect(36, needed);
246 expect_dword(buf, 28);
247 trace("buf[1] = %08x\n", buf[1]);
248 expect_magic(buf + 2);
249 expect_dword(buf + 3, 0);
250 expect_dword(buf + 4, RGNDATA_RECT);
251 expect_float(buf + 5, 10.0);
252 expect_float(buf + 6, 20.0);
253 expect_float(buf + 7, 100.0);
254 expect_float(buf + 8, 200.0);
255 expect_dword(buf + 10, 0xeeeeeeee);
256 test_region_data(buf, needed, __LINE__);
257
258 rect.X = 50;
259 rect.Y = 30;
260 rect.Width = 10;
261 rect.Height = 20;
262 status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
263 ok(status == Ok, "status %08x\n", status);
264 rect.X = 100;
265 rect.Y = 300;
266 rect.Width = 30;
267 rect.Height = 50;
268 status = GdipCombineRegionRectI(region, &rect, CombineModeXor);
269 ok(status == Ok, "status %08x\n", status);
270
271 rect.X = 200;
272 rect.Y = 100;
273 rect.Width = 133;
274 rect.Height = 266;
275 status = GdipCreateRegionRectI(&rect, &region2);
276 ok(status == Ok, "status %08x\n", status);
277 rect.X = 20;
278 rect.Y = 10;
279 rect.Width = 40;
280 rect.Height = 66;
281 status = GdipCombineRegionRectI(region2, &rect, CombineModeUnion);
282 ok(status == Ok, "status %08x\n", status);
283
284 status = GdipCombineRegionRegion(region, region2, CombineModeComplement);
285 ok(status == Ok, "status %08x\n", status);
286
287 rect.X = 400;
288 rect.Y = 500;
289 rect.Width = 22;
290 rect.Height = 55;
291 status = GdipCombineRegionRectI(region, &rect, CombineModeExclude);
292 ok(status == Ok, "status %08x\n", status);
293
294 status = GdipGetRegionDataSize(region, &needed);
295 ok(status == Ok, "status %08x\n", status);
296 expect(156, needed);
297 memset(buf, 0xee, sizeof(buf));
298 needed = 0;
299 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
300 ok(status == Ok, "status %08x\n", status);
301 expect(156, needed);
302 expect_dword(buf, 148);
303 trace("buf[1] = %08x\n", buf[1]);
304 expect_magic(buf + 2);
305 expect_dword(buf + 3, 10);
306 expect_dword(buf + 4, CombineModeExclude);
307 expect_dword(buf + 5, CombineModeComplement);
308 expect_dword(buf + 6, CombineModeXor);
309 expect_dword(buf + 7, CombineModeIntersect);
310 expect_dword(buf + 8, RGNDATA_RECT);
311 expect_float(buf + 9, 10.0);
312 expect_float(buf + 10, 20.0);
313 expect_float(buf + 11, 100.0);
314 expect_float(buf + 12, 200.0);
315 expect_dword(buf + 13, RGNDATA_RECT);
316 expect_float(buf + 14, 50.0);
317 expect_float(buf + 15, 30.0);
318 expect_float(buf + 16, 10.0);
319 expect_float(buf + 17, 20.0);
320 expect_dword(buf + 18, RGNDATA_RECT);
321 expect_float(buf + 19, 100.0);
322 expect_float(buf + 20, 300.0);
323 expect_float(buf + 21, 30.0);
324 expect_float(buf + 22, 50.0);
325 expect_dword(buf + 23, CombineModeUnion);
326 expect_dword(buf + 24, RGNDATA_RECT);
327 expect_float(buf + 25, 200.0);
328 expect_float(buf + 26, 100.0);
329 expect_float(buf + 27, 133.0);
330 expect_float(buf + 28, 266.0);
331 expect_dword(buf + 29, RGNDATA_RECT);
332 expect_float(buf + 30, 20.0);
333 expect_float(buf + 31, 10.0);
334 expect_float(buf + 32, 40.0);
335 expect_float(buf + 33, 66.0);
336 expect_dword(buf + 34, RGNDATA_RECT);
337 expect_float(buf + 35, 400.0);
338 expect_float(buf + 36, 500.0);
339 expect_float(buf + 37, 22.0);
340 expect_float(buf + 38, 55.0);
341 expect_dword(buf + 39, 0xeeeeeeee);
342 test_region_data(buf, needed, __LINE__);
343
344 status = GdipDeleteRegion(region2);
345 ok(status == Ok, "status %08x\n", status);
346 status = GdipDeleteRegion(region);
347 ok(status == Ok, "status %08x\n", status);
348
349 /* Try some paths */
350
351 status = GdipCreatePath(FillModeAlternate, &path);
352 ok(status == Ok, "status %08x\n", status);
353 GdipAddPathRectangle(path, 12.5, 13.0, 14.0, 15.0);
354
355 status = GdipCreateRegionPath(path, &region);
356 ok(status == Ok, "status %08x\n", status);
357 status = GdipGetRegionDataSize(region, &needed);
358 ok(status == Ok, "status %08x\n", status);
359 expect(72, needed);
360 memset(buf, 0xee, sizeof(buf));
361 needed = 0;
362 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
363 ok(status == Ok, "status %08x\n", status);
364 expect(72, needed);
365 expect_dword(buf, 64);
366 trace("buf[1] = %08x\n", buf[1]);
367 expect_magic(buf + 2);
368 expect_dword(buf + 3, 0);
369 expect_dword(buf + 4, RGNDATA_PATH);
370 expect_dword(buf + 5, 0x00000030);
371 expect_magic(buf + 6);
372 expect_dword(buf + 7, 0x00000004);
373 expect_dword(buf + 8, 0x00000000);
374 expect_float(buf + 9, 12.5);
375 expect_float(buf + 10, 13.0);
376 expect_float(buf + 11, 26.5);
377 expect_float(buf + 12, 13.0);
378 expect_float(buf + 13, 26.5);
379 expect_float(buf + 14, 28.0);
380 expect_float(buf + 15, 12.5);
381 expect_float(buf + 16, 28.0);
382 expect_dword(buf + 17, 0x81010100);
383 expect_dword(buf + 18, 0xeeeeeeee);
384 test_region_data(buf, needed, __LINE__);
385
386 rect.X = 50;
387 rect.Y = 30;
388 rect.Width = 10;
389 rect.Height = 20;
390 status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
391 ok(status == Ok, "status %08x\n", status);
392 status = GdipGetRegionDataSize(region, &needed);
393 ok(status == Ok, "status %08x\n", status);
394 expect(96, needed);
395 memset(buf, 0xee, sizeof(buf));
396 needed = 0;
397 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
398 ok(status == Ok, "status %08x\n", status);
399 expect(96, needed);
400 expect_dword(buf, 88);
401 trace("buf[1] = %08x\n", buf[1]);
402 expect_magic(buf + 2);
403 expect_dword(buf + 3, 2);
404 expect_dword(buf + 4, CombineModeIntersect);
405 expect_dword(buf + 5, RGNDATA_PATH);
406 expect_dword(buf + 6, 0x00000030);
407 expect_magic(buf + 7);
408 expect_dword(buf + 8, 0x00000004);
409 expect_dword(buf + 9, 0x00000000);
410 expect_float(buf + 10, 12.5);
411 expect_float(buf + 11, 13.0);
412 expect_float(buf + 12, 26.5);
413 expect_float(buf + 13, 13.0);
414 expect_float(buf + 14, 26.5);
415 expect_float(buf + 15, 28.0);
416 expect_float(buf + 16, 12.5);
417 expect_float(buf + 17, 28.0);
418 expect_dword(buf + 18, 0x81010100);
419 expect_dword(buf + 19, RGNDATA_RECT);
420 expect_float(buf + 20, 50.0);
421 expect_float(buf + 21, 30.0);
422 expect_float(buf + 22, 10.0);
423 expect_float(buf + 23, 20.0);
424 expect_dword(buf + 24, 0xeeeeeeee);
425 test_region_data(buf, needed, __LINE__);
426
427 status = GdipDeleteRegion(region);
428 ok(status == Ok, "status %08x\n", status);
429 status = GdipDeletePath(path);
430 ok(status == Ok, "status %08x\n", status);
431
432 /* Test an empty path */
433 status = GdipCreatePath(FillModeAlternate, &path);
434 expect(Ok, status);
435 status = GdipCreateRegionPath(path, &region);
436 expect(Ok, status);
437 status = GdipGetRegionDataSize(region, &needed);
438 expect(Ok, status);
439 expect(36, needed);
440 memset(buf, 0xee, sizeof(buf));
441 needed = 0;
442 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
443 expect(Ok, status);
444 expect(36, needed);
445 expect_dword(buf, 28);
446 trace("buf[1] = %08x\n", buf[1]);
447 expect_magic(buf + 2);
448 expect_dword(buf + 3, 0);
449 expect_dword(buf + 4, RGNDATA_PATH);
450 /* Second signature for pathdata */
451 expect_dword(buf + 5, 12);
452 expect_magic(buf + 6);
453 expect_dword(buf + 7, 0);
454 /* flags 0 means that a path is an array of FLOATs */
455 ok(*(buf + 8) == 0x4000 /* before win7 */ || *(buf + 8) == 0,
456 "expected 0x4000 or 0, got %08x\n", *(buf + 8));
457 expect_dword(buf + 10, 0xeeeeeeee);
458 test_region_data(buf, needed, __LINE__);
459
460 /* Transform an empty region */
461 status = GdipCreateMatrix(&matrix);
462 expect(Ok, status);
463 status = GdipTransformRegion(region, matrix);
464 expect(Ok, status);
465 GdipDeleteMatrix(matrix);
466
467 status = GdipDeleteRegion(region);
468 expect(Ok, status);
469
470 /* Test a simple triangle of INTs */
471 status = GdipAddPathLine(path, 5, 6, 7, 8);
472 expect(Ok, status);
473 status = GdipAddPathLine(path, 8, 1, 5, 6);
474 expect(Ok, status);
475 status = GdipClosePathFigure(path);
476 expect(Ok, status);
477 status = GdipCreateRegionPath(path, &region);
478 expect(Ok, status);
479 status = GdipGetRegionDataSize(region, &needed);
480 expect(Ok, status);
481 expect(56, needed);
482 memset(buf, 0xee, sizeof(buf));
483 needed = 0;
484 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
485 expect(Ok, status);
486 expect(56, needed);
487 expect_dword(buf, 48);
488 trace("buf[1] = %08x\n", buf[1]);
489 expect_magic(buf + 2);
490 expect_dword(buf + 3 , 0);
491 expect_dword(buf + 4 , RGNDATA_PATH);
492 expect_dword(buf + 5, 32);
493 expect_magic(buf + 6);
494 expect_dword(buf + 7, 4);
495 /* flags 0x4000 means that a path is an array of shorts instead of FLOATs */
496 expect_dword(buf + 8, 0x4000);
497
498 point = (RegionDataPoint*)(buf + 9);
499 expect(5, point[0].X);
500 expect(6, point[0].Y);
501 expect(7, point[1].X); /* buf + 10 */
502 expect(8, point[1].Y);
503 expect(8, point[2].X); /* buf + 11 */
504 expect(1, point[2].Y);
505 expect(5, point[3].X); /* buf + 12 */
506 expect(6, point[3].Y);
507 expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */
508 expect_dword(buf + 14, 0xeeeeeeee);
509 test_region_data(buf, needed, __LINE__);
510
511 status = GdipTranslateRegion(region, 0.6, 0.8);
512 expect(Ok, status);
513 memset(buf, 0xee, sizeof(buf));
514 needed = 0;
515 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
516 expect(Ok, status);
517 expect(72, needed);
518 expect_dword(buf, 64);
519 expect_magic(buf + 2);
520 expect_dword(buf + 3 , 0);
521 expect_dword(buf + 4 , RGNDATA_PATH);
522 expect_dword(buf + 5, 48);
523 expect_magic(buf + 6);
524 expect_dword(buf + 7, 4);
525 /* flags 0 means that a path is an array of FLOATs */
526 expect_dword(buf + 8, 0);
527 expect_float(buf + 9, 5.6);
528 expect_float(buf + 10, 6.8);
529 expect_float(buf + 11, 7.6);
530 expect_float(buf + 12, 8.8);
531 expect_float(buf + 13, 8.6);
532 expect_float(buf + 14, 1.8);
533 expect_float(buf + 15, 5.6);
534 expect_float(buf + 16, 6.8);
535 expect_dword(buf + 17, 0x81010100); /* 0x01010100 if we don't close the path */
536 expect_dword(buf + 18, 0xeeeeeeee);
537 test_region_data(buf, needed, __LINE__);
538
539 status = GdipDeletePath(path);
540 expect(Ok, status);
541 status = GdipDeleteRegion(region);
542 expect(Ok, status);
543
544 /* Test a floating-point triangle */
545 status = GdipCreatePath(FillModeAlternate, &path);
546 expect(Ok, status);
547 status = GdipAddPathLine(path, 5.6, 6.2, 7.2, 8.9);
548 expect(Ok, status);
549 status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2);
550 expect(Ok, status);
551 status = GdipCreateRegionPath(path, &region);
552 expect(Ok, status);
553 status = GdipGetRegionDataSize(region, &needed);
554 expect(Ok, status);
555 expect(72, needed);
556 memset(buf, 0xee, sizeof(buf));
557 needed = 0;
558 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
559 expect(Ok, status);
560 expect(72, needed);
561 expect_dword(buf, 64);
562 trace("buf[1] = %08x\n", buf[1]);
563 expect_magic(buf + 2);
564 expect_dword(buf + 3, 0);
565 expect_dword(buf + 4, RGNDATA_PATH);
566 expect_dword(buf + 5, 48);
567 expect_magic(buf + 6);
568 expect_dword(buf + 7, 4);
569 expect_dword(buf + 8, 0);
570 expect_float(buf + 9, 5.6);
571 expect_float(buf + 10, 6.2);
572 expect_float(buf + 11, 7.2);
573 expect_float(buf + 12, 8.9);
574 expect_float(buf + 13, 8.1);
575 expect_float(buf + 14, 1.6);
576 expect_float(buf + 15, 5.6);
577 expect_float(buf + 16, 6.2);
578 expect_dword(buf + 17, 0x01010100);
579 expect_dword(buf + 18, 0xeeeeeeee);
580 test_region_data(buf, needed, __LINE__);
581
582 status = GdipDeletePath(path);
583 expect(Ok, status);
584 status = GdipDeleteRegion(region);
585 expect(Ok, status);
586
587 /* Test for a path with > 4 points, and CombineRegionPath */
588 GdipCreatePath(FillModeAlternate, &path);
589 status = GdipAddPathLine(path, 50, 70.2, 60, 102.8);
590 expect(Ok, status);
591 status = GdipAddPathLine(path, 55.4, 122.4, 40.4, 60.2);
592 expect(Ok, status);
593 status = GdipAddPathLine(path, 45.6, 20.2, 50, 70.2);
594 expect(Ok, status);
595 rect.X = 20;
596 rect.Y = 25;
597 rect.Width = 60;
598 rect.Height = 120;
599 status = GdipCreateRegionRectI(&rect, &region);
600 expect(Ok, status);
601 status = GdipCombineRegionPath(region, path, CombineModeUnion);
602 expect(Ok, status);
603
604 status = GdipGetRegionDataSize(region, &needed);
605 expect(Ok, status);
606 expect(116, needed);
607 memset(buf, 0xee, sizeof(buf));
608 needed = 0;
609 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
610 expect(Ok, status);
611 expect(116, needed);
612 expect_dword(buf, 108);
613 trace("buf[1] = %08x\n", buf[1]);
614 expect_magic(buf + 2);
615 expect_dword(buf + 3, 2);
616 expect_dword(buf + 4, CombineModeUnion);
617 expect_dword(buf + 5, RGNDATA_RECT);
618 expect_float(buf + 6, 20.0);
619 expect_float(buf + 7, 25.0);
620 expect_float(buf + 8, 60.0);
621 expect_float(buf + 9, 120.0);
622 expect_dword(buf + 10, RGNDATA_PATH);
623 expect_dword(buf + 11, 68);
624 expect_magic(buf + 12);
625 expect_dword(buf + 13, 6);
626 expect_float(buf + 14, 0.0);
627 expect_float(buf + 15, 50.0);
628 expect_float(buf + 16, 70.2);
629 expect_float(buf + 17, 60.0);
630 expect_float(buf + 18, 102.8);
631 expect_float(buf + 19, 55.4);
632 expect_float(buf + 20, 122.4);
633 expect_float(buf + 21, 40.4);
634 expect_float(buf + 22, 60.2);
635 expect_float(buf + 23, 45.6);
636 expect_float(buf + 24, 20.2);
637 expect_float(buf + 25, 50.0);
638 expect_float(buf + 26, 70.2);
639 expect_dword(buf + 27, 0x01010100);
640 ok(*(buf + 28) == 0x00000101 || *(buf + 28) == 0x43050101 /* Win 7 */,
641 "expected 00000101 or 43050101 got %08x\n", *(buf + 28));
642 expect_dword(buf + 29, 0xeeeeeeee);
643 test_region_data(buf, needed, __LINE__);
644
645 status = GdipDeletePath(path);
646 expect(Ok, status);
647 status = GdipDeleteRegion(region);
648 expect(Ok, status);
649
650 /* Test how shorts are stored in the region path data */
651 status = GdipCreatePath(FillModeAlternate, &path);
652 ok(status == Ok, "status %08x\n", status);
653 GdipAddPathRectangleI(path, -1969, -1974, 1995, 1997);
654
655 status = GdipCreateRegionPath(path, &region);
656 ok(status == Ok, "status %08x\n", status);
657 needed = 0;
658 status = GdipGetRegionDataSize(region, &needed);
659 ok(status == Ok, "status %08x\n", status);
660 expect(56, needed);
661 memset(buf, 0xee, sizeof(buf));
662 needed = 0;
663 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
664 ok(status == Ok, "status %08x\n", status);
665 expect(56, needed);
666 expect_dword(buf, 48);
667 trace("buf[1] = %08x\n", buf[1]);
668 expect_magic(buf + 2);
669 expect_dword(buf + 3, 0);
670 expect_dword(buf + 4, RGNDATA_PATH);
671 expect_dword(buf + 5, 32);
672 expect_magic(buf + 6);
673 expect_dword(buf + 7, 4);
674 /* flags 0x4000 means that a path is an array of shorts instead of FLOATs */
675 expect_dword(buf + 8, 0x4000);
676 point = (RegionDataPoint*)(buf + 9);
677 expect(-1969, point[0].X);
678 expect(-1974, point[0].Y);
679 expect(26, point[1].X); /* buf + 10 */
680 expect(-1974, point[1].Y);
681 expect(26, point[2].X); /* buf + 11 */
682 expect(23, point[2].Y);
683 expect(-1969, point[3].X); /* buf + 12 */
684 expect(23, point[3].Y);
685 expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */
686 expect_dword(buf + 14, 0xeeeeeeee);
687 test_region_data(buf, needed, __LINE__);
688
689 status = GdipDeletePath(path);
690 expect(Ok, status);
691 status = GdipDeleteRegion(region);
692 expect(Ok, status);
693
694 /* Test with integers that can't be stored as shorts */
695 status = GdipCreatePath(FillModeAlternate, &path);
696 ok(status == Ok, "status %08x\n", status);
697 GdipAddPathRectangleI(path, -196900, -197400, 199500, 199700);
698
699 status = GdipCreateRegionPath(path, &region);
700 ok(status == Ok, "status %08x\n", status);
701 needed = 0;
702 status = GdipGetRegionDataSize(region, &needed);
703 ok(status == Ok, "status %08x\n", status);
704 expect(72, needed);
705 memset(buf, 0xee, sizeof(buf));
706 needed = 0;
707 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
708 ok(status == Ok, "status %08x\n", status);
709 expect(72, needed);
710 expect_dword(buf, 64);
711 trace("buf[1] = %08x\n", buf[1]);
712 expect_magic(buf + 2);
713 expect_dword(buf + 3, 0);
714 expect_dword(buf + 4, RGNDATA_PATH);
715 expect_dword(buf + 5, 48);
716 expect_magic(buf + 6);
717 expect_dword(buf + 7, 4);
718 /* flags 0 means that a path is an array of FLOATs */
719 expect_dword(buf + 8, 0);
720 expect_float(buf + 9, -196900.0);
721 expect_float(buf + 10, -197400.0);
722 expect_float(buf + 11, 2600.0);
723 expect_float(buf + 12, -197400.0);
724 expect_float(buf + 13, 2600.0);
725 expect_float(buf + 14, 2300.0);
726 expect_float(buf + 15, -196900.0);
727 expect_float(buf + 16, 2300.0);
728 expect_dword(buf + 17, 0x81010100); /* 0x01010100 if we don't close the path */
729 expect_dword(buf + 18, 0xeeeeeeee);
730 test_region_data(buf, needed, __LINE__);
731
732 status = GdipDeletePath(path);
733 expect(Ok, status);
734 status = GdipDeleteRegion(region);
735 expect(Ok, status);
736
737 /* Test beziers */
738 GdipCreatePath(FillModeAlternate, &path);
739 /* Exactly 90 degrees */
740 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
741 expect(Ok, status);
742 /* Over 90 degrees */
743 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
744 expect(Ok, status);
745 status = GdipCreateRegionPath(path, &region);
746 ok(status == Ok, "status %08x\n", status);
747 needed = 0;
748 status = GdipGetRegionDataSize(region, &needed);
749 ok(status == Ok, "status %08x\n", status);
750 expect(136, needed);
751 memset(buf, 0xee, sizeof(buf));
752 needed = 0;
753 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
754 ok(status == Ok, "status %08x\n", status);
755 expect(136, needed);
756 expect_dword(buf, 128);
757 trace("buf[1] = %08x\n", buf[1]);
758 expect_magic(buf + 2);
759 expect_dword(buf + 3, 0);
760 expect_dword(buf + 4, RGNDATA_PATH);
761 expect_dword(buf + 5, 112);
762 expect_magic(buf + 6);
763 expect_dword(buf + 7, 11);
764 /* flags 0 means that a path is an array of FLOATs */
765 expect_dword(buf + 8, 0);
766 expect_float(buf + 9, 600.0);
767 expect_float(buf + 10, 450.0);
768 expect_float(buf + 11, 600.0);
769 expect_float(buf + 12, 643.299561);
770 expect_float(buf + 13, 488.071198);
771 expect_float(buf + 14, 800.0);
772 expect_float(buf + 15, 350.0);
773 expect_float(buf + 16, 800.0);
774 expect_float(buf + 17, 600.0);
775 expect_float(buf + 18, 450.0);
776 expect_float(buf + 19, 600.0);
777 expect_float(buf + 20, 643.299622);
778 expect_float(buf + 21, 488.071167);
779 expect_float(buf + 22, 800.0);
780 expect_float(buf + 23, 350.0);
781 expect_float(buf + 24, 800.0);
782 expect_float(buf + 25, 329.807129);
783 expect_float(buf + 26, 800.0);
784 expect_float(buf + 27, 309.688568);
785 expect_float(buf + 28, 796.574890);
786 expect_float(buf + 29, 290.084167);
787 expect_float(buf + 30, 789.799561);
788 expect_dword(buf + 31, 0x03030300);
789 expect_dword(buf + 32, 0x03030301);
790 ok(*(buf + 33) == 0x00030303 /* before win7 */ ||
791 *(buf + 33) == 0x43030303 /* 32-bit win7 */ || *(buf + 33) == 0x4c030303 /* 64-bit win7 */,
792 "expected 0x00030303 or 0x43030303 or 0x4c030303 got %08x\n", *(buf + 33));
793 expect_dword(buf + 34, 0xeeeeeeee);
794 test_region_data(buf, needed, __LINE__);
795
796 status = GdipDeletePath(path);
797 expect(Ok, status);
798 status = GdipDeleteRegion(region);
799 expect(Ok, status);
800 }
801
802 static void test_isinfinite(void)
803 {
804 GpStatus status;
805 GpRegion *region;
806 GpGraphics *graphics = NULL;
807 GpMatrix *m;
808 HDC hdc = GetDC(0);
809 BOOL res;
810
811 status = GdipCreateFromHDC(hdc, &graphics);
812 expect(Ok, status);
813 GdipCreateRegion(&region);
814
815 GdipCreateMatrix2(3.0, 0.0, 0.0, 1.0, 20.0, 30.0, &m);
816
817 /* NULL arguments */
818 status = GdipIsInfiniteRegion(NULL, NULL, NULL);
819 expect(InvalidParameter, status);
820 status = GdipIsInfiniteRegion(region, NULL, NULL);
821 expect(InvalidParameter, status);
822 status = GdipIsInfiniteRegion(NULL, graphics, NULL);
823 expect(InvalidParameter, status);
824 status = GdipIsInfiniteRegion(NULL, NULL, &res);
825 expect(InvalidParameter, status);
826 status = GdipIsInfiniteRegion(region, NULL, &res);
827 expect(InvalidParameter, status);
828
829 res = FALSE;
830 status = GdipIsInfiniteRegion(region, graphics, &res);
831 expect(Ok, status);
832 expect(TRUE, res);
833
834 /* after world transform */
835 status = GdipSetWorldTransform(graphics, m);
836 expect(Ok, status);
837
838 res = FALSE;
839 status = GdipIsInfiniteRegion(region, graphics, &res);
840 expect(Ok, status);
841 expect(TRUE, res);
842
843 GdipDeleteMatrix(m);
844 GdipDeleteRegion(region);
845 GdipDeleteGraphics(graphics);
846 ReleaseDC(0, hdc);
847 }
848
849 static void test_isempty(void)
850 {
851 GpStatus status;
852 GpRegion *region;
853 GpGraphics *graphics = NULL;
854 HDC hdc = GetDC(0);
855 BOOL res;
856
857 status = GdipCreateFromHDC(hdc, &graphics);
858 expect(Ok, status);
859 GdipCreateRegion(&region);
860
861 /* NULL arguments */
862 status = GdipIsEmptyRegion(NULL, NULL, NULL);
863 expect(InvalidParameter, status);
864 status = GdipIsEmptyRegion(region, NULL, NULL);
865 expect(InvalidParameter, status);
866 status = GdipIsEmptyRegion(NULL, graphics, NULL);
867 expect(InvalidParameter, status);
868 status = GdipIsEmptyRegion(NULL, NULL, &res);
869 expect(InvalidParameter, status);
870 status = GdipIsEmptyRegion(region, NULL, &res);
871 expect(InvalidParameter, status);
872
873 /* default is infinite */
874 res = TRUE;
875 status = GdipIsEmptyRegion(region, graphics, &res);
876 expect(Ok, status);
877 expect(FALSE, res);
878
879 status = GdipSetEmpty(region);
880 expect(Ok, status);
881
882 res = FALSE;
883 status = GdipIsEmptyRegion(region, graphics, &res);
884 expect(Ok, status);
885 expect(TRUE, res);
886
887 GdipDeleteRegion(region);
888 GdipDeleteGraphics(graphics);
889 ReleaseDC(0, hdc);
890 }
891
892 static void test_combinereplace(void)
893 {
894 GpStatus status;
895 GpRegion *region, *region2;
896 GpPath *path;
897 GpRectF rectf;
898 UINT needed;
899 DWORD buf[50];
900
901 rectf.X = rectf.Y = 0.0;
902 rectf.Width = rectf.Height = 100.0;
903
904 status = GdipCreateRegionRect(&rectf, &region);
905 expect(Ok, status);
906
907 /* replace with the same rectangle */
908 status = GdipCombineRegionRect(region, &rectf,CombineModeReplace);
909 expect(Ok, status);
910
911 status = GdipGetRegionDataSize(region, &needed);
912 expect(Ok, status);
913 expect(36, needed);
914 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
915 expect(Ok, status);
916 expect(36, needed);
917 expect_dword(buf, 28);
918 trace("buf[1] = %08x\n", buf[1]);
919 expect_magic(buf + 2);
920 expect_dword(buf + 3, 0);
921 expect_dword(buf + 4, RGNDATA_RECT);
922
923 /* replace with path */
924 status = GdipCreatePath(FillModeAlternate, &path);
925 expect(Ok, status);
926 status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 250.0);
927 expect(Ok, status);
928 status = GdipCombineRegionPath(region, path, CombineModeReplace);
929 expect(Ok, status);
930
931 status = GdipGetRegionDataSize(region, &needed);
932 expect(Ok, status);
933 expect(156, needed);
934 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
935 expect(Ok, status);
936 expect(156, needed);
937 expect_dword(buf, 148);
938 trace("buf[1] = %08x\n", buf[1]);
939 expect_magic(buf + 2);
940 expect_dword(buf + 3, 0);
941 expect_dword(buf + 4, RGNDATA_PATH);
942 GdipDeletePath(path);
943
944 /* replace with infinite rect */
945 status = GdipCreateRegion(&region2);
946 expect(Ok, status);
947 status = GdipCombineRegionRegion(region, region2, CombineModeReplace);
948 expect(Ok, status);
949
950 status = GdipGetRegionDataSize(region, &needed);
951 expect(Ok, status);
952 expect(20, needed);
953 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
954 expect(Ok, status);
955 expect(20, needed);
956 expect_dword(buf, 12);
957 trace("buf[1] = %08x\n", buf[1]);
958 expect_magic(buf + 2);
959 expect_dword(buf + 3, 0);
960 expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
961 GdipDeleteRegion(region2);
962
963 /* more complex case : replace with a combined region */
964 status = GdipCreateRegionRect(&rectf, &region2);
965 expect(Ok, status);
966 status = GdipCreatePath(FillModeAlternate, &path);
967 expect(Ok, status);
968 status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 250.0);
969 expect(Ok, status);
970 status = GdipCombineRegionPath(region2, path, CombineModeUnion);
971 expect(Ok, status);
972 GdipDeletePath(path);
973 status = GdipCombineRegionRegion(region, region2, CombineModeReplace);
974 expect(Ok, status);
975 GdipDeleteRegion(region2);
976
977 status = GdipGetRegionDataSize(region, &needed);
978 expect(Ok, status);
979 expect(180, needed);
980 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
981 expect(Ok, status);
982 expect(180, needed);
983 expect_dword(buf, 172);
984 trace("buf[1] = %08x\n", buf[1]);
985 expect_magic(buf + 2);
986 expect_dword(buf + 3, 2);
987 expect_dword(buf + 4, CombineModeUnion);
988
989 GdipDeleteRegion(region);
990 }
991
992 static void test_fromhrgn(void)
993 {
994 GpStatus status;
995 GpRegion *region = (GpRegion*)0xabcdef01;
996 HRGN hrgn;
997 UINT needed;
998 DWORD buf[220];
999 RegionDataPoint *point;
1000 GpGraphics *graphics = NULL;
1001 HDC hdc;
1002 BOOL res;
1003
1004 /* NULL */
1005 status = GdipCreateRegionHrgn(NULL, NULL);
1006 expect(InvalidParameter, status);
1007 status = GdipCreateRegionHrgn(NULL, &region);
1008 expect(InvalidParameter, status);
1009 status = GdipCreateRegionHrgn((HRGN)0xdeadbeef, &region);
1010 expect(InvalidParameter, status);
1011 ok(region == (GpRegion*)0xabcdef01, "Expected region not to be created\n");
1012
1013 /* empty rectangle */
1014 hrgn = CreateRectRgn(0, 0, 0, 0);
1015 status = GdipCreateRegionHrgn(hrgn, &region);
1016 expect(Ok, status);
1017 if(status == Ok) {
1018
1019 hdc = GetDC(0);
1020 status = GdipCreateFromHDC(hdc, &graphics);
1021 expect(Ok, status);
1022 res = FALSE;
1023 status = GdipIsEmptyRegion(region, graphics, &res);
1024 expect(Ok, status);
1025 expect(TRUE, res);
1026 GdipDeleteGraphics(graphics);
1027 ReleaseDC(0, hdc);
1028 GdipDeleteRegion(region);
1029
1030 }
1031 DeleteObject(hrgn);
1032
1033 /* rectangle */
1034 hrgn = CreateRectRgn(0, 0, 100, 10);
1035 status = GdipCreateRegionHrgn(hrgn, &region);
1036 expect(Ok, status);
1037
1038 status = GdipGetRegionDataSize(region, &needed);
1039 expect(Ok, status);
1040 expect(56, needed);
1041
1042 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
1043 expect(Ok, status);
1044
1045 if(status == Ok){
1046
1047 expect(56, needed);
1048 expect_dword(buf, 48);
1049 expect_magic(buf + 2);
1050 expect_dword(buf + 3, 0);
1051 expect_dword(buf + 4, RGNDATA_PATH);
1052 expect_dword(buf + 5, 0x00000020);
1053 expect_magic(buf + 6);
1054 expect_dword(buf + 7, 0x00000004);
1055 todo_wine expect_dword(buf + 8, 0x00006000); /* ?? */
1056
1057 point = (RegionDataPoint*)buf + 9;
1058
1059 expect(0, point[0].X);
1060 expect(0, point[0].Y);
1061
1062 expect(100,point[1].X); /* buf + 10 */
1063 expect(0, point[1].Y);
1064 expect(100,point[2].X); /* buf + 11 */
1065 expect(10, point[2].Y);
1066
1067 expect(0, point[3].X); /* buf + 12 */
1068
1069 expect(10, point[3].Y);
1070 expect_dword(buf + 13, 0x81010100); /* closed */
1071
1072 }
1073
1074 GdipDeleteRegion(region);
1075 DeleteObject(hrgn);
1076
1077 /* ellipse */
1078 hrgn = CreateEllipticRgn(0, 0, 100, 10);
1079 status = GdipCreateRegionHrgn(hrgn, &region);
1080 expect(Ok, status);
1081
1082 status = GdipGetRegionDataSize(region, &needed);
1083 expect(Ok, status);
1084 ok(needed == 216 ||
1085 needed == 196, /* win98 */
1086 "Got %.8x\n", needed);
1087
1088 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
1089 expect(Ok, status);
1090
1091 if(status == Ok && needed == 216) /* Don't try to test win98 layout */
1092 {
1093 expect(Ok, status);
1094 expect(216, needed);
1095 expect_dword(buf, 208);
1096 expect_magic(buf + 2);
1097 expect_dword(buf + 3, 0);
1098 expect_dword(buf + 4, RGNDATA_PATH);
1099 expect_dword(buf + 5, 0x000000C0);
1100 expect_magic(buf + 6);
1101 expect_dword(buf + 7, 0x00000024);
1102 todo_wine expect_dword(buf + 8, 0x00006000); /* ?? */
1103 }
1104
1105 GdipDeleteRegion(region);
1106 DeleteObject(hrgn);
1107 }
1108
1109 static void test_gethrgn(void)
1110 {
1111 GpStatus status;
1112 GpRegion *region, *region2;
1113 GpPath *path;
1114 GpGraphics *graphics;
1115 HRGN hrgn;
1116 HDC hdc=GetDC(0);
1117 INT rgntype;
1118 RECT rgnbox;
1119 static const RECT empty_rect = {0,0,0,0};
1120 static const RECT test_rect = {10, 11, 20, 21};
1121 static const GpRectF test_rectF = {10.0, 11.0, 10.0, 10.0};
1122 static const RECT scaled_rect = {20, 22, 40, 42};
1123 static const RECT test_rect2 = {10, 21, 20, 31};
1124 static const GpRectF test_rect2F = {10.0, 21.0, 10.0, 10.0};
1125 static const RECT test_rect3 = {10, 11, 20, 31};
1126 static const GpRectF test_rect3F = {10.0, 11.0, 10.0, 20.0};
1127
1128 status = GdipCreateFromHDC(hdc, &graphics);
1129 ok(status == Ok, "status %08x\n", status);
1130
1131 status = GdipCreateRegion(&region);
1132 ok(status == Ok, "status %08x\n", status);
1133
1134 status = GdipGetRegionHRgn(NULL, graphics, &hrgn);
1135 ok(status == InvalidParameter, "status %08x\n", status);
1136 status = GdipGetRegionHRgn(region, graphics, NULL);
1137 ok(status == InvalidParameter, "status %08x\n", status);
1138
1139 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1140 ok(status == Ok, "status %08x\n", status);
1141 ok(hrgn == NULL, "hrgn=%p\n", hrgn);
1142
1143 status = GdipGetRegionHRgn(region, graphics, &hrgn);
1144 ok(status == Ok, "status %08x\n", status);
1145 ok(hrgn == NULL, "hrgn=%p\n", hrgn);
1146
1147 status = GdipSetEmpty(region);
1148 ok(status == Ok, "status %08x\n", status);
1149 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1150 ok(status == Ok, "status %08x\n", status);
1151 verify_region(hrgn, &empty_rect);
1152 DeleteObject(hrgn);
1153
1154 status = GdipCreatePath(FillModeAlternate, &path);
1155 ok(status == Ok, "status %08x\n", status);
1156 status = GdipAddPathRectangle(path, 10.0, 11.0, 10.0, 10.0);
1157 ok(status == Ok, "status %08x\n", status);
1158
1159 status = GdipCreateRegionPath(path, &region2);
1160 ok(status == Ok, "status %08x\n", status);
1161 status = GdipGetRegionHRgn(region2, NULL, &hrgn);
1162 ok(status == Ok, "status %08x\n", status);
1163 verify_region(hrgn, &test_rect);
1164 DeleteObject(hrgn);
1165
1166 /* resulting HRGN is in device coordinates */
1167 status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
1168 ok(status == Ok, "status %08x\n", status);
1169 status = GdipGetRegionHRgn(region2, graphics, &hrgn);
1170 ok(status == Ok, "status %08x\n", status);
1171 verify_region(hrgn, &scaled_rect);
1172 DeleteObject(hrgn);
1173
1174 status = GdipCombineRegionRect(region2, &test_rectF, CombineModeReplace);
1175 ok(status == Ok, "status %08x\n", status);
1176 status = GdipGetRegionHRgn(region2, NULL, &hrgn);
1177 ok(status == Ok, "status %08x\n", status);
1178 verify_region(hrgn, &test_rect);
1179 DeleteObject(hrgn);
1180
1181 status = GdipGetRegionHRgn(region2, graphics, &hrgn);
1182 ok(status == Ok, "status %08x\n", status);
1183 verify_region(hrgn, &scaled_rect);
1184 DeleteObject(hrgn);
1185
1186 status = GdipSetInfinite(region);
1187 ok(status == Ok, "status %08x\n", status);
1188 status = GdipCombineRegionRect(region, &test_rectF, CombineModeIntersect);
1189 ok(status == Ok, "status %08x\n", status);
1190 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1191 ok(status == Ok, "status %08x\n", status);
1192 verify_region(hrgn, &test_rect);
1193 DeleteObject(hrgn);
1194
1195 status = GdipCombineRegionRect(region, &test_rectF, CombineModeReplace);
1196 ok(status == Ok, "status %08x\n", status);
1197 status = GdipCombineRegionRect(region, &test_rect2F, CombineModeUnion);
1198 ok(status == Ok, "status %08x\n", status);
1199 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1200 ok(status == Ok, "status %08x\n", status);
1201 verify_region(hrgn, &test_rect3);
1202 DeleteObject(hrgn);
1203
1204 status = GdipCombineRegionRect(region, &test_rect3F, CombineModeReplace);
1205 ok(status == Ok, "status %08x\n", status);
1206 status = GdipCombineRegionRect(region, &test_rect2F, CombineModeXor);
1207 ok(status == Ok, "status %08x\n", status);
1208 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1209 ok(status == Ok, "status %08x\n", status);
1210 verify_region(hrgn, &test_rect);
1211 DeleteObject(hrgn);
1212
1213 status = GdipCombineRegionRect(region, &test_rect3F, CombineModeReplace);
1214 ok(status == Ok, "status %08x\n", status);
1215 status = GdipCombineRegionRect(region, &test_rectF, CombineModeExclude);
1216 ok(status == Ok, "status %08x\n", status);
1217 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1218 ok(status == Ok, "status %08x\n", status);
1219 verify_region(hrgn, &test_rect2);
1220 DeleteObject(hrgn);
1221
1222 status = GdipCombineRegionRect(region, &test_rectF, CombineModeReplace);
1223 ok(status == Ok, "status %08x\n", status);
1224 status = GdipCombineRegionRect(region, &test_rect3F, CombineModeComplement);
1225 ok(status == Ok, "status %08x\n", status);
1226 status = GdipGetRegionHRgn(region, NULL, &hrgn);
1227 ok(status == Ok, "status %08x\n", status);
1228 verify_region(hrgn, &test_rect2);
1229 DeleteObject(hrgn);
1230
1231 status = GdipDeletePath(path);
1232 ok(status == Ok, "status %08x\n", status);
1233 status = GdipDeleteRegion(region);
1234 ok(status == Ok, "status %08x\n", status);
1235 status = GdipDeleteRegion(region2);
1236 ok(status == Ok, "status %08x\n", status);
1237 status = GdipDeleteGraphics(graphics);
1238 ok(status == Ok, "status %08x\n", status);
1239
1240 /* test with gdi32 transform */
1241 SetViewportOrgEx(hdc, 10, 10, NULL);
1242
1243 status = GdipCreateFromHDC(hdc, &graphics);
1244 expect(Ok, status);
1245
1246 status = GdipCreateRegionRect(&test_rectF, &region);
1247 expect(Ok, status);
1248
1249 status = GdipGetRegionHRgn(region, graphics, &hrgn);
1250 expect(Ok, status);
1251
1252 rgntype = GetRgnBox(hrgn, &rgnbox);
1253 DeleteObject(hrgn);
1254
1255 expect(SIMPLEREGION, rgntype);
1256 expect(20, rgnbox.left);
1257 expect(21, rgnbox.top);
1258 expect(30, rgnbox.right);
1259 expect(31, rgnbox.bottom);
1260
1261 status = GdipDeleteRegion(region);
1262 expect(Ok, status);
1263 status = GdipDeleteGraphics(graphics);
1264 expect(Ok, status);
1265
1266 SetViewportOrgEx(hdc, 0, 0, NULL);
1267
1268 ReleaseDC(0, hdc);
1269 }
1270
1271 static void test_isequal(void)
1272 {
1273 GpRegion *region1, *region2;
1274 GpGraphics *graphics;
1275 GpRectF rectf;
1276 GpStatus status;
1277 HDC hdc = GetDC(0);
1278 BOOL res;
1279
1280 status = GdipCreateFromHDC(hdc, &graphics);
1281 ok(status == Ok, "status %08x\n", status);
1282
1283 status = GdipCreateRegion(&region1);
1284 ok(status == Ok, "status %08x\n", status);
1285 status = GdipCreateRegion(&region2);
1286 ok(status == Ok, "status %08x\n", status);
1287
1288 /* NULL */
1289 status = GdipIsEqualRegion(NULL, NULL, NULL, NULL);
1290 ok(status == InvalidParameter, "status %08x\n", status);
1291 status = GdipIsEqualRegion(region1, region2, NULL, NULL);
1292 ok(status == InvalidParameter, "status %08x\n", status);
1293 status = GdipIsEqualRegion(region1, region2, graphics, NULL);
1294 ok(status == InvalidParameter, "status %08x\n", status);
1295 status = GdipIsEqualRegion(region1, region2, NULL, &res);
1296 ok(status == InvalidParameter, "status %08x\n", status);
1297
1298 /* infinite regions */
1299 res = FALSE;
1300 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1301 ok(status == Ok, "status %08x\n", status);
1302 ok(res, "Expected to be equal.\n");
1303 /* empty regions */
1304 status = GdipSetEmpty(region1);
1305 ok(status == Ok, "status %08x\n", status);
1306 status = GdipSetEmpty(region2);
1307 ok(status == Ok, "status %08x\n", status);
1308 res = FALSE;
1309 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1310 ok(status == Ok, "status %08x\n", status);
1311 ok(res, "Expected to be equal.\n");
1312 /* empty & infinite */
1313 status = GdipSetInfinite(region1);
1314 ok(status == Ok, "status %08x\n", status);
1315 res = TRUE;
1316 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1317 ok(status == Ok, "status %08x\n", status);
1318 ok(!res, "Expected to be unequal.\n");
1319 /* rect & (inf/empty) */
1320 rectf.X = rectf.Y = 0.0;
1321 rectf.Width = rectf.Height = 100.0;
1322 status = GdipCombineRegionRect(region1, &rectf, CombineModeReplace);
1323 ok(status == Ok, "status %08x\n", status);
1324 res = TRUE;
1325 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1326 ok(status == Ok, "status %08x\n", status);
1327 ok(!res, "Expected to be unequal.\n");
1328 status = GdipSetInfinite(region2);
1329 ok(status == Ok, "status %08x\n", status);
1330 res = TRUE;
1331 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1332 ok(status == Ok, "status %08x\n", status);
1333 ok(!res, "Expected to be unequal.\n");
1334 /* roughly equal rectangles */
1335 rectf.X = rectf.Y = 0.0;
1336 rectf.Width = rectf.Height = 100.001;
1337 status = GdipCombineRegionRect(region2, &rectf, CombineModeReplace);
1338 ok(status == Ok, "status %08x\n", status);
1339 res = FALSE;
1340 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1341 ok(status == Ok, "status %08x\n", status);
1342 ok(res, "Expected to be equal.\n");
1343 /* equal rectangles */
1344 rectf.X = rectf.Y = 0.0;
1345 rectf.Width = rectf.Height = 100.0;
1346 status = GdipCombineRegionRect(region2, &rectf, CombineModeReplace);
1347 ok(status == Ok, "status %08x\n", status);
1348 res = FALSE;
1349 status = GdipIsEqualRegion(region1, region2, graphics, &res);
1350 ok(status == Ok, "status %08x\n", status);
1351 ok(res, "Expected to be equal.\n");
1352
1353 /* cleanup */
1354 status = GdipDeleteRegion(region1);
1355 ok(status == Ok, "status %08x\n", status);
1356 status = GdipDeleteRegion(region2);
1357 ok(status == Ok, "status %08x\n", status);
1358 status = GdipDeleteGraphics(graphics);
1359 ok(status == Ok, "status %08x\n", status);
1360 ReleaseDC(0, hdc);
1361 }
1362
1363 static void test_translate(void)
1364 {
1365 GpRegion *region, *region2;
1366 GpGraphics *graphics;
1367 GpPath *path;
1368 GpRectF rectf;
1369 GpStatus status;
1370 HDC hdc = GetDC(0);
1371 BOOL res;
1372
1373 status = GdipCreateFromHDC(hdc, &graphics);
1374 ok(status == Ok, "status %08x\n", status);
1375
1376 status = GdipCreatePath(FillModeAlternate, &path);
1377 ok(status == Ok, "status %08x\n", status);
1378
1379 status = GdipCreateRegion(&region);
1380 ok(status == Ok, "status %08x\n", status);
1381 status = GdipCreateRegion(&region2);
1382 ok(status == Ok, "status %08x\n", status);
1383
1384 /* NULL */
1385 status = GdipTranslateRegion(NULL, 0.0, 0.0);
1386 ok(status == InvalidParameter, "status %08x\n", status);
1387
1388 /* infinite */
1389 status = GdipTranslateRegion(region, 10.0, 10.0);
1390 ok(status == Ok, "status %08x\n", status);
1391 /* empty */
1392 status = GdipSetEmpty(region);
1393 ok(status == Ok, "status %08x\n", status);
1394 status = GdipTranslateRegion(region, 10.0, 10.0);
1395 ok(status == Ok, "status %08x\n", status);
1396 /* rect */
1397 rectf.X = 10.0; rectf.Y = 0.0;
1398 rectf.Width = rectf.Height = 100.0;
1399 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1400 ok(status == Ok, "status %08x\n", status);
1401 rectf.X = 15.0; rectf.Y = -2.0;
1402 rectf.Width = rectf.Height = 100.0;
1403 status = GdipCombineRegionRect(region2, &rectf, CombineModeReplace);
1404 ok(status == Ok, "status %08x\n", status);
1405 status = GdipTranslateRegion(region, 5.0, -2.0);
1406 ok(status == Ok, "status %08x\n", status);
1407 res = FALSE;
1408 status = GdipIsEqualRegion(region, region2, graphics, &res);
1409 ok(status == Ok, "status %08x\n", status);
1410 ok(res, "Expected to be equal.\n");
1411 /* path */
1412 status = GdipAddPathEllipse(path, 0.0, 10.0, 100.0, 150.0);
1413 ok(status == Ok, "status %08x\n", status);
1414 status = GdipCombineRegionPath(region, path, CombineModeReplace);
1415 ok(status == Ok, "status %08x\n", status);
1416 status = GdipResetPath(path);
1417 ok(status == Ok, "status %08x\n", status);
1418 status = GdipAddPathEllipse(path, 10.0, 21.0, 100.0, 150.0);
1419 ok(status == Ok, "status %08x\n", status);
1420 status = GdipCombineRegionPath(region2, path, CombineModeReplace);
1421 ok(status == Ok, "status %08x\n", status);
1422 status = GdipTranslateRegion(region, 10.0, 11.0);
1423 ok(status == Ok, "status %08x\n", status);
1424 res = FALSE;
1425 status = GdipIsEqualRegion(region, region2, graphics, &res);
1426 ok(status == Ok, "status %08x\n", status);
1427 ok(res, "Expected to be equal.\n");
1428
1429 status = GdipDeleteRegion(region);
1430 ok(status == Ok, "status %08x\n", status);
1431 status = GdipDeleteRegion(region2);
1432 ok(status == Ok, "status %08x\n", status);
1433 status = GdipDeleteGraphics(graphics);
1434 ok(status == Ok, "status %08x\n", status);
1435 status = GdipDeletePath(path);
1436 ok(status == Ok, "status %08x\n", status);
1437 ReleaseDC(0, hdc);
1438 }
1439
1440 static void test_transform(void)
1441 {
1442 GpRegion *region, *region2;
1443 GpMatrix *matrix;
1444 GpGraphics *graphics;
1445 GpPath *path;
1446 GpRectF rectf;
1447 GpStatus status;
1448 HDC hdc = GetDC(0);
1449 BOOL res;
1450
1451 status = GdipCreateFromHDC(hdc, &graphics);
1452 expect(Ok, status);
1453
1454 status = GdipCreatePath(FillModeAlternate, &path);
1455 expect(Ok, status);
1456
1457 status = GdipCreateRegion(&region);
1458 expect(Ok, status);
1459 status = GdipCreateRegion(&region2);
1460 expect(Ok, status);
1461
1462 status = GdipCreateMatrix(&matrix);
1463 expect(Ok, status);
1464 status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend);
1465 expect(Ok, status);
1466
1467 /* NULL */
1468 status = GdipTransformRegion(NULL, matrix);
1469 expect(InvalidParameter, status);
1470
1471 status = GdipTransformRegion(region, NULL);
1472 expect(InvalidParameter, status);
1473
1474 /* infinite */
1475 status = GdipTransformRegion(region, matrix);
1476 expect(Ok, status);
1477
1478 res = FALSE;
1479 status = GdipIsEqualRegion(region, region2, graphics, &res);
1480 expect(Ok, status);
1481 ok(res, "Expected to be equal.\n");
1482
1483 /* empty */
1484 status = GdipSetEmpty(region);
1485 expect(Ok, status);
1486 status = GdipTransformRegion(region, matrix);
1487 expect(Ok, status);
1488
1489 status = GdipSetEmpty(region2);
1490 expect(Ok, status);
1491
1492 res = FALSE;
1493 status = GdipIsEqualRegion(region, region2, graphics, &res);
1494 expect(Ok, status);
1495 ok(res, "Expected to be equal.\n");
1496
1497 /* rect */
1498 rectf.X = 10.0;
1499 rectf.Y = 0.0;
1500 rectf.Width = rectf.Height = 100.0;
1501 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1502 expect(Ok, status);
1503 rectf.X = 20.0;
1504 rectf.Y = 0.0;
1505 rectf.Width = 200.0;
1506 rectf.Height = 300.0;
1507 status = GdipCombineRegionRect(region2, &rectf, CombineModeReplace);
1508 expect(Ok, status);
1509 status = GdipTransformRegion(region, matrix);
1510 expect(Ok, status);
1511 res = FALSE;
1512 status = GdipIsEqualRegion(region, region2, graphics, &res);
1513 expect(Ok, status);
1514 ok(res, "Expected to be equal.\n");
1515
1516 /* path */
1517 status = GdipAddPathEllipse(path, 0.0, 10.0, 100.0, 150.0);
1518 expect(Ok, status);
1519 status = GdipCombineRegionPath(region, path, CombineModeReplace);
1520 expect(Ok, status);
1521 status = GdipResetPath(path);
1522 expect(Ok, status);
1523 status = GdipAddPathEllipse(path, 0.0, 30.0, 200.0, 450.0);
1524 expect(Ok, status);
1525 status = GdipCombineRegionPath(region2, path, CombineModeReplace);
1526 expect(Ok, status);
1527 status = GdipTransformRegion(region, matrix);
1528 expect(Ok, status);
1529 res = FALSE;
1530 status = GdipIsEqualRegion(region, region2, graphics, &res);
1531 expect(Ok, status);
1532 ok(res, "Expected to be equal.\n");
1533
1534 status = GdipDeleteRegion(region);
1535 expect(Ok, status);
1536 status = GdipDeleteRegion(region2);
1537 expect(Ok, status);
1538 status = GdipDeleteGraphics(graphics);
1539 expect(Ok, status);
1540 status = GdipDeletePath(path);
1541 expect(Ok, status);
1542 status = GdipDeleteMatrix(matrix);
1543 expect(Ok, status);
1544 ReleaseDC(0, hdc);
1545 }
1546
1547 static void test_scans(void)
1548 {
1549 GpRegion *region;
1550 GpMatrix *matrix;
1551 GpRectF rectf;
1552 GpStatus status;
1553 ULONG count=80085;
1554 INT icount;
1555 GpRectF scans[2];
1556 GpRect scansi[2];
1557
1558 status = GdipCreateRegion(&region);
1559 expect(Ok, status);
1560
1561 status = GdipCreateMatrix(&matrix);
1562 expect(Ok, status);
1563
1564 /* test NULL values */
1565 status = GdipGetRegionScansCount(NULL, &count, matrix);
1566 expect(InvalidParameter, status);
1567
1568 status = GdipGetRegionScansCount(region, NULL, matrix);
1569 expect(InvalidParameter, status);
1570
1571 status = GdipGetRegionScansCount(region, &count, NULL);
1572 expect(InvalidParameter, status);
1573
1574 status = GdipGetRegionScans(NULL, scans, &icount, matrix);
1575 expect(InvalidParameter, status);
1576
1577 status = GdipGetRegionScans(region, scans, NULL, matrix);
1578 expect(InvalidParameter, status);
1579
1580 status = GdipGetRegionScans(region, scans, &icount, NULL);
1581 expect(InvalidParameter, status);
1582
1583 /* infinite */
1584 status = GdipGetRegionScansCount(region, &count, matrix);
1585 expect(Ok, status);
1586 expect(1, count);
1587
1588 status = GdipGetRegionScans(region, NULL, &icount, matrix);
1589 expect(Ok, status);
1590 expect(1, icount);
1591
1592 status = GdipGetRegionScans(region, scans, &icount, matrix);
1593 expect(Ok, status);
1594 expect(1, icount);
1595
1596 status = GdipGetRegionScansI(region, scansi, &icount, matrix);
1597 expect(Ok, status);
1598 expect(1, icount);
1599 expect(-0x400000, scansi[0].X);
1600 expect(-0x400000, scansi[0].Y);
1601 expect(0x800000, scansi[0].Width);
1602 expect(0x800000, scansi[0].Height);
1603
1604 status = GdipGetRegionScans(region, scans, &icount, matrix);
1605 expect(Ok, status);
1606 expect(1, icount);
1607 expectf((double)-0x400000, scans[0].X);
1608 expectf((double)-0x400000, scans[0].Y);
1609 expectf((double)0x800000, scans[0].Width);
1610 expectf((double)0x800000, scans[0].Height);
1611
1612 /* empty */
1613 status = GdipSetEmpty(region);
1614 expect(Ok, status);
1615
1616 status = GdipGetRegionScansCount(region, &count, matrix);
1617 expect(Ok, status);
1618 expect(0, count);
1619
1620 status = GdipGetRegionScans(region, scans, &icount, matrix);
1621 expect(Ok, status);
1622 expect(0, icount);
1623
1624 /* single rectangle */
1625 rectf.X = rectf.Y = 0.0;
1626 rectf.Width = rectf.Height = 5.0;
1627 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1628 expect(Ok, status);
1629
1630 status = GdipGetRegionScansCount(region, &count, matrix);
1631 expect(Ok, status);
1632 expect(1, count);
1633
1634 status = GdipGetRegionScans(region, scans, &icount, matrix);
1635 expect(Ok, status);
1636 expect(1, icount);
1637 expectf(0.0, scans[0].X);
1638 expectf(0.0, scans[0].Y);
1639 expectf(5.0, scans[0].Width);
1640 expectf(5.0, scans[0].Height);
1641
1642 /* two rectangles */
1643 rectf.X = rectf.Y = 5.0;
1644 rectf.Width = rectf.Height = 5.0;
1645 status = GdipCombineRegionRect(region, &rectf, CombineModeUnion);
1646 expect(Ok, status);
1647
1648 status = GdipGetRegionScansCount(region, &count, matrix);
1649 expect(Ok, status);
1650 expect(2, count);
1651
1652 /* Native ignores the initial value of count */
1653 scans[1].X = scans[1].Y = scans[1].Width = scans[1].Height = 8.0;
1654 icount = 1;
1655 status = GdipGetRegionScans(region, scans, &icount, matrix);
1656 expect(Ok, status);
1657 expect(2, icount);
1658 expectf(0.0, scans[0].X);
1659 expectf(0.0, scans[0].Y);
1660 expectf(5.0, scans[0].Width);
1661 expectf(5.0, scans[0].Height);
1662 expectf(5.0, scans[1].X);
1663 expectf(5.0, scans[1].Y);
1664 expectf(5.0, scans[1].Width);
1665 expectf(5.0, scans[1].Height);
1666
1667 status = GdipGetRegionScansI(region, scansi, &icount, matrix);
1668 expect(Ok, status);
1669 expect(2, icount);
1670 expect(0, scansi[0].X);
1671 expect(0, scansi[0].Y);
1672 expect(5, scansi[0].Width);
1673 expect(5, scansi[0].Height);
1674 expect(5, scansi[1].X);
1675 expect(5, scansi[1].Y);
1676 expect(5, scansi[1].Width);
1677 expect(5, scansi[1].Height);
1678
1679 status = GdipDeleteRegion(region);
1680 expect(Ok, status);
1681 status = GdipDeleteMatrix(matrix);
1682 expect(Ok, status);
1683 }
1684
1685 static void test_getbounds(void)
1686 {
1687 GpRegion *region;
1688 GpGraphics *graphics;
1689 GpStatus status;
1690 GpRectF rectf;
1691 HDC hdc = GetDC(0);
1692
1693 status = GdipCreateFromHDC(hdc, &graphics);
1694 ok(status == Ok, "status %08x\n", status);
1695 status = GdipCreateRegion(&region);
1696 ok(status == Ok, "status %08x\n", status);
1697
1698 /* NULL */
1699 status = GdipGetRegionBounds(NULL, NULL, NULL);
1700 ok(status == InvalidParameter, "status %08x\n", status);
1701 status = GdipGetRegionBounds(region, NULL, NULL);
1702 ok(status == InvalidParameter, "status %08x\n", status);
1703 status = GdipGetRegionBounds(region, graphics, NULL);
1704 ok(status == InvalidParameter, "status %08x\n", status);
1705 /* infinite */
1706 rectf.X = rectf.Y = 0.0;
1707 rectf.Height = rectf.Width = 100.0;
1708 status = GdipGetRegionBounds(region, graphics, &rectf);
1709 ok(status == Ok, "status %08x\n", status);
1710 ok(rectf.X == -(REAL)(1 << 22), "Expected X = %.2f, got %.2f\n", -(REAL)(1 << 22), rectf.X);
1711 ok(rectf.Y == -(REAL)(1 << 22), "Expected Y = %.2f, got %.2f\n", -(REAL)(1 << 22), rectf.Y);
1712 ok(rectf.Width == (REAL)(1 << 23), "Expected width = %.2f, got %.2f\n", (REAL)(1 << 23), rectf.Width);
1713 ok(rectf.Height == (REAL)(1 << 23), "Expected height = %.2f, got %.2f\n",(REAL)(1 << 23), rectf.Height);
1714 /* empty */
1715 rectf.X = rectf.Y = 0.0;
1716 rectf.Height = rectf.Width = 100.0;
1717 status = GdipSetEmpty(region);
1718 ok(status == Ok, "status %08x\n", status);
1719 status = GdipGetRegionBounds(region, graphics, &rectf);
1720 ok(status == Ok, "status %08x\n", status);
1721 ok(rectf.X == 0.0, "Expected X = 0.0, got %.2f\n", rectf.X);
1722 ok(rectf.Y == 0.0, "Expected Y = 0.0, got %.2f\n", rectf.Y);
1723 ok(rectf.Width == 0.0, "Expected width = 0.0, got %.2f\n", rectf.Width);
1724 ok(rectf.Height == 0.0, "Expected height = 0.0, got %.2f\n", rectf.Height);
1725 /* rect */
1726 rectf.X = 10.0; rectf.Y = 0.0;
1727 rectf.Width = rectf.Height = 100.0;
1728 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1729 ok(status == Ok, "status %08x\n", status);
1730 rectf.X = rectf.Y = 0.0;
1731 rectf.Height = rectf.Width = 0.0;
1732 status = GdipGetRegionBounds(region, graphics, &rectf);
1733 ok(status == Ok, "status %08x\n", status);
1734 ok(rectf.X == 10.0, "Expected X = 0.0, got %.2f\n", rectf.X);
1735 ok(rectf.Y == 0.0, "Expected Y = 0.0, got %.2f\n", rectf.Y);
1736 ok(rectf.Width == 100.0, "Expected width = 0.0, got %.2f\n", rectf.Width);
1737 ok(rectf.Height == 100.0, "Expected height = 0.0, got %.2f\n", rectf.Height);
1738
1739 /* the world and page transforms are ignored */
1740 GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
1741 GdipSetPageUnit(graphics, UnitInch);
1742 GdipSetPageScale(graphics, 2.0);
1743 status = GdipGetRegionBounds(region, graphics, &rectf);
1744 ok(status == Ok, "status %08x\n", status);
1745 ok(rectf.X == 10.0, "Expected X = 0.0, got %.2f\n", rectf.X);
1746 ok(rectf.Y == 0.0, "Expected Y = 0.0, got %.2f\n", rectf.Y);
1747 ok(rectf.Width == 100.0, "Expected width = 0.0, got %.2f\n", rectf.Width);
1748
1749 rectf.X = 10.0; rectf.Y = 0.0;
1750 rectf.Width = rectf.Height = 100.0;
1751 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1752 ok(status == Ok, "status %08x\n", status);
1753 rectf.X = rectf.Y = 0.0;
1754 rectf.Height = rectf.Width = 0.0;
1755 status = GdipGetRegionBounds(region, graphics, &rectf);
1756 ok(status == Ok, "status %08x\n", status);
1757 ok(rectf.X == 10.0, "Expected X = 0.0, got %.2f\n", rectf.X);
1758 ok(rectf.Y == 0.0, "Expected Y = 0.0, got %.2f\n", rectf.Y);
1759 ok(rectf.Width == 100.0, "Expected width = 0.0, got %.2f\n", rectf.Width);
1760 ok(rectf.Height == 100.0, "Expected height = 0.0, got %.2f\n", rectf.Height);
1761
1762 status = GdipDeleteRegion(region);
1763 ok(status == Ok, "status %08x\n", status);
1764 status = GdipDeleteGraphics(graphics);
1765 ok(status == Ok, "status %08x\n", status);
1766 ReleaseDC(0, hdc);
1767 }
1768
1769 static void test_isvisiblepoint(void)
1770 {
1771 HDC hdc = GetDC(0);
1772 GpGraphics* graphics;
1773 GpRegion* region;
1774 GpPath* path;
1775 GpRectF rectf;
1776 GpStatus status;
1777 BOOL res;
1778 REAL x, y;
1779
1780 status = GdipCreateFromHDC(hdc, &graphics);
1781 expect(Ok, status);
1782
1783 status = GdipCreateRegion(&region);
1784 expect(Ok, status);
1785
1786 /* null parameters */
1787 status = GdipIsVisibleRegionPoint(NULL, 0, 0, graphics, &res);
1788 expect(InvalidParameter, status);
1789 status = GdipIsVisibleRegionPointI(NULL, 0, 0, graphics, &res);
1790 expect(InvalidParameter, status);
1791
1792 status = GdipIsVisibleRegionPoint(region, 0, 0, NULL, &res);
1793 expect(Ok, status);
1794 status = GdipIsVisibleRegionPointI(region, 0, 0, NULL, &res);
1795 expect(Ok, status);
1796
1797 status = GdipIsVisibleRegionPoint(region, 0, 0, graphics, NULL);
1798 expect(InvalidParameter, status);
1799 status = GdipIsVisibleRegionPointI(region, 0, 0, graphics, NULL);
1800 expect(InvalidParameter, status);
1801
1802 /* infinite region */
1803 status = GdipIsInfiniteRegion(region, graphics, &res);
1804 expect(Ok, status);
1805 ok(res == TRUE, "Region should be infinite\n");
1806
1807 x = 10;
1808 y = 10;
1809 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1810 expect(Ok, status);
1811 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1812 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1813 expect(Ok, status);
1814 ok(res == TRUE, "Expected (%d, %d) to be visible\n", (INT)x, (INT)y);
1815
1816 x = -10;
1817 y = -10;
1818 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1819 expect(Ok, status);
1820 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1821 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1822 expect(Ok, status);
1823 ok(res == TRUE, "Expected (%d, %d) to be visible\n", (INT)x, (INT)y);
1824
1825 /* rectangular region */
1826 rectf.X = 10;
1827 rectf.Y = 20;
1828 rectf.Width = 30;
1829 rectf.Height = 40;
1830
1831 status = GdipCombineRegionRect(region, &rectf, CombineModeReplace);
1832 expect(Ok, status);
1833
1834 x = 0;
1835 y = 0;
1836 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1837 expect(Ok, status);
1838 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1839 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1840 expect(Ok, status);
1841 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1842
1843 x = 9;
1844 y = 19;
1845 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1846 expect(Ok, status);
1847 ok(res == FALSE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1848
1849 x = 9.25;
1850 y = 19.25;
1851 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1852 expect(Ok, status);
1853 ok(res == FALSE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1854
1855 x = 9.5;
1856 y = 19.5;
1857 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1858 expect(Ok, status);
1859 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1860
1861 x = 9.75;
1862 y = 19.75;
1863 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1864 expect(Ok, status);
1865 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1866
1867 x = 10;
1868 y = 20;
1869 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1870 expect(Ok, status);
1871 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1872
1873 x = 25;
1874 y = 40;
1875 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1876 expect(Ok, status);
1877 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1878 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1879 expect(Ok, status);
1880 ok(res == TRUE, "Expected (%d, %d) to be visible\n", (INT)x, (INT)y);
1881
1882 x = 40;
1883 y = 60;
1884 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1885 expect(Ok, status);
1886 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1887 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1888 expect(Ok, status);
1889 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1890
1891 /* translate into the center of the rectangle */
1892 status = GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
1893 expect(Ok, status);
1894
1895 /* native ignores the world transform, so treat these as if
1896 * no transform exists */
1897 x = -20;
1898 y = -30;
1899 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1900 expect(Ok, status);
1901 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1902 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1903 expect(Ok, status);
1904 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1905
1906 x = 0;
1907 y = 0;
1908 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1909 expect(Ok, status);
1910 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1911 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1912 expect(Ok, status);
1913 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1914
1915 x = 25;
1916 y = 40;
1917 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1918 expect(Ok, status);
1919 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1920 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1921 expect(Ok, status);
1922 ok(res == TRUE, "Expected (%d, %d) to be visible\n", (INT)x, (INT)y);
1923
1924 /* translate back to origin */
1925 status = GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
1926 expect(Ok, status);
1927
1928 /* region from path */
1929 status = GdipCreatePath(FillModeAlternate, &path);
1930 expect(Ok, status);
1931
1932 status = GdipAddPathEllipse(path, 10, 20, 30, 40);
1933 expect(Ok, status);
1934
1935 status = GdipCombineRegionPath(region, path, CombineModeReplace);
1936 expect(Ok, status);
1937
1938 x = 11;
1939 y = 21;
1940 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1941 expect(Ok, status);
1942 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1943 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1944 expect(Ok, status);
1945 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1946
1947 x = 25;
1948 y = 40;
1949 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1950 expect(Ok, status);
1951 ok(res == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
1952 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1953 expect(Ok, status);
1954 ok(res == TRUE, "Expected (%d, %d) to be visible\n", (INT)x, (INT)y);
1955
1956 x = 40;
1957 y = 60;
1958 status = GdipIsVisibleRegionPoint(region, x, y, graphics, &res);
1959 expect(Ok, status);
1960 ok(res == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
1961 status = GdipIsVisibleRegionPointI(region, (INT)x, (INT)y, graphics, &res);
1962 expect(Ok, status);
1963 ok(res == FALSE, "Expected (%d, %d) not to be visible\n", (INT)x, (INT)y);
1964
1965 GdipDeletePath(path);
1966
1967 GdipDeleteRegion(region);
1968 GdipDeleteGraphics(graphics);
1969 ReleaseDC(0, hdc);
1970 }
1971
1972 static void test_isvisiblerect(void)
1973 {
1974 HDC hdc = GetDC(0);
1975 GpGraphics* graphics;
1976 GpRegion* region;
1977 GpPath* path;
1978 GpRectF rectf;
1979 GpStatus status;
1980 BOOL res;
1981 REAL x, y, w, h;
1982
1983 status = GdipCreateFromHDC(hdc, &graphics);
1984 expect(Ok, status);
1985
1986 status = GdipCreateRegion(&region);
1987 expect(Ok, status);
1988
1989 /* null parameters */
1990 status = GdipIsVisibleRegionRect(NULL, 0, 0, 0, 0, graphics, &res);
1991 expect(InvalidParameter, status);
1992 status = GdipIsVisibleRegionRectI(NULL, 0, 0, 0, 0, graphics, &res);
1993 expect(InvalidParameter, status);
1994
1995 status = GdipIsVisibleRegionRect(region, 0, 0, 0, 0, NULL, &res);
1996 expect(Ok, status);
1997 status = GdipIsVisibleRegionRectI(region, 0, 0, 0, 0, NULL, &res);
1998 expect(Ok, status);
1999
2000 status = GdipIsVisibleRegionRect(region, 0, 0, 0, 0, graphics, NULL);
2001 expect(InvalidParameter, status);
2002 status = GdipIsVisibleRegionRectI(region, 0, 0, 0, 0, graphics, NULL);
2003 expect(InvalidParameter, status);
2004
2005 /* infinite region */
2006 status = GdipIsInfiniteRegion(region, graphics, &res);
2007 expect(Ok, status);
2008 ok(res == TRUE, "Region should be infinite\n");
2009
2010 x = 10; w = 10;
2011 y = 10; h = 10;
2012 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2013 expect(Ok, status);
2014 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2015
2016 x = -10; w = 5;
2017 y = -10; h = 5;
2018 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2019 expect(Ok, status);
2020 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2021
2022 /* rectangular region */
2023 rectf.X = 10;
2024 rectf.Y = 20;
2025 rectf.Width = 30;
2026 rectf.Height = 40;
2027
2028 status = GdipCombineRegionRect(region, &rectf, CombineModeIntersect);
2029 expect(Ok, status);
2030
2031 /* entirely within the region */
2032 x = 11; w = 10;
2033 y = 12; h = 10;
2034 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2035 expect(Ok, status);
2036 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2037 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2038 expect(Ok, status);
2039 ok(res == TRUE, "Expected (%d, %d, %d, %d) to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2040
2041 /* entirely outside of the region */
2042 x = 0; w = 5;
2043 y = 0; h = 5;
2044 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2045 expect(Ok, status);
2046 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2047 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2048 expect(Ok, status);
2049 ok(res == FALSE, "Expected (%d, %d, %d, %d) not to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2050
2051 /* corner cases */
2052 x = 0; w = 10;
2053 y = 0; h = 20;
2054 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2055 expect(Ok, status);
2056 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2057
2058 x = 0; w = 10.25;
2059 y = 0; h = 20.25;
2060 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2061 expect(Ok, status);
2062 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2063
2064 x = 39; w = 10;
2065 y = 59; h = 10;
2066 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2067 expect(Ok, status);
2068 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2069
2070 x = 39.25; w = 10;
2071 y = 59.25; h = 10;
2072 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2073 expect(Ok, status);
2074 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2075
2076 /* corners outside, but some intersection */
2077 x = 0; w = 100;
2078 y = 0; h = 100;
2079 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2080 expect(Ok, status);
2081 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2082
2083 x = 0; w = 100;
2084 y = 0; h = 40;
2085 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2086 expect(Ok, status);
2087 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2088
2089 x = 0; w = 25;
2090 y = 0; h = 100;
2091 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2092 expect(Ok, status);
2093 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2094
2095 /* translate into the center of the rectangle */
2096 status = GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2097 expect(Ok, status);
2098
2099 /* native ignores the world transform, so treat these as if
2100 * no transform exists */
2101 x = 0; w = 5;
2102 y = 0; h = 5;
2103 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2104 expect(Ok, status);
2105 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2106 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2107 expect(Ok, status);
2108 ok(res == FALSE, "Expected (%d, %d, %d, %d) not to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2109
2110 x = 11; w = 10;
2111 y = 12; h = 10;
2112 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2113 expect(Ok, status);
2114 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2115 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2116 expect(Ok, status);
2117 ok(res == TRUE, "Expected (%d, %d, %d, %d) to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2118
2119 /* translate back to origin */
2120 status = GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2121 expect(Ok, status);
2122
2123 /* region from path */
2124 status = GdipCreatePath(FillModeAlternate, &path);
2125 expect(Ok, status);
2126
2127 status = GdipAddPathEllipse(path, 10, 20, 30, 40);
2128 expect(Ok, status);
2129
2130 status = GdipCombineRegionPath(region, path, CombineModeReplace);
2131 expect(Ok, status);
2132
2133 x = 0; w = 12;
2134 y = 0; h = 22;
2135 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2136 expect(Ok, status);
2137 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2138 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2139 expect(Ok, status);
2140 ok(res == FALSE, "Expected (%d, %d, %d, %d) not to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2141
2142 x = 0; w = 25;
2143 y = 0; h = 40;
2144 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2145 expect(Ok, status);
2146 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2147 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2148 expect(Ok, status);
2149 ok(res == TRUE, "Expected (%d, %d, %d, %d) to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2150
2151 x = 38; w = 10;
2152 y = 55; h = 10;
2153 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2154 expect(Ok, status);
2155 ok(res == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, w, h);
2156 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2157 expect(Ok, status);
2158 ok(res == FALSE, "Expected (%d, %d, %d, %d) not to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2159
2160 x = 0; w = 100;
2161 y = 0; h = 100;
2162 status = GdipIsVisibleRegionRect(region, x, y, w, h, graphics, &res);
2163 expect(Ok, status);
2164 ok(res == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, w, h);
2165 status = GdipIsVisibleRegionRectI(region, (INT)x, (INT)y, (INT)w, (INT)h, graphics, &res);
2166 expect(Ok, status);
2167 ok(res == TRUE, "Expected (%d, %d, %d, %d) to be visible\n", (INT)x, (INT)y, (INT)w, (INT)h);
2168
2169 GdipDeletePath(path);
2170
2171 GdipDeleteRegion(region);
2172 GdipDeleteGraphics(graphics);
2173 ReleaseDC(0, hdc);
2174 }
2175
2176 static void test_excludeinfinite(void)
2177 {
2178 GpStatus status;
2179 GpRegion *region;
2180 UINT count=0xdeadbeef;
2181 GpRectF scans[4];
2182 GpMatrix *identity;
2183 static const RectF rect_exclude = {0.0, 0.0, 1.0, 1.0};
2184
2185 status = GdipCreateMatrix(&identity);
2186 expect(Ok, status);
2187
2188 status = GdipCreateRegion(&region);
2189 expect(Ok, status);
2190
2191 status = GdipCombineRegionRect(region, &rect_exclude, CombineModeExclude);
2192 expect(Ok, status);
2193
2194 status = GdipGetRegionScansCount(region, &count, identity);
2195 expect(Ok, status);
2196 expect(4, count);
2197
2198 count = 4;
2199 status = GdipGetRegionScans(region, scans, (INT*)&count, identity);
2200 expect(Ok, status);
2201
2202 expectf(-4194304.0, scans[0].X);
2203 expectf(-4194304.0, scans[0].Y);
2204 expectf(8388608.0, scans[0].Width);
2205 expectf(4194304.0, scans[0].Height);
2206
2207 expectf(-4194304.0, scans[1].X);
2208 expectf(0.0, scans[1].Y);
2209 expectf(4194304.0, scans[1].Width);
2210 expectf(1.0, scans[1].Height);
2211
2212 expectf(1.0, scans[2].X);
2213 expectf(0.0, scans[2].Y);
2214 expectf(4194303.0, scans[2].Width);
2215 expectf(1.0, scans[2].Height);
2216
2217 expectf(-4194304.0, scans[3].X);
2218 expectf(1.0, scans[3].Y);
2219 expectf(8388608.0, scans[3].Width);
2220 expectf(4194303.0, scans[3].Height);
2221
2222 GdipDeleteRegion(region);
2223 GdipDeleteMatrix(identity);
2224 }
2225
2226 static void test_GdipCreateRegionRgnData(void)
2227 {
2228 GpGraphics *graphics = NULL;
2229 GpRegion *region, *region2;
2230 HDC hdc = GetDC(0);
2231 GpStatus status;
2232 BYTE buf[512];
2233 UINT needed;
2234 BOOL ret;
2235
2236 status = GdipCreateRegionRgnData(NULL, 0, NULL);
2237 ok(status == InvalidParameter, "status %d\n", status);
2238
2239 status = GdipCreateFromHDC(hdc, &graphics);
2240 ok(status == Ok, "status %d\n", status);
2241
2242 status = GdipCreateRegion(&region);
2243 ok(status == Ok, "status %d\n", status);
2244
2245 /* infinite region */
2246 memset(buf, 0xee, sizeof(buf));
2247 needed = 0;
2248 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
2249 ok(status == Ok, "status %d\n", status);
2250 expect(20, needed);
2251
2252 status = GdipCreateRegionRgnData(buf, needed, NULL);
2253 ok(status == InvalidParameter, "status %d\n", status);
2254
2255 status = GdipCreateRegionRgnData(buf, needed, &region2);
2256 ok(status == Ok, "status %d\n", status);
2257
2258 ret = FALSE;
2259 status = GdipIsInfiniteRegion(region2, graphics, &ret);
2260 ok(status == Ok, "status %d\n", status);
2261 ok(ret, "got %d\n", ret);
2262 GdipDeleteRegion(region2);
2263
2264 /* empty region */
2265 status = GdipSetEmpty(region);
2266 ok(status == Ok, "status %d\n", status);
2267
2268 memset(buf, 0xee, sizeof(buf));
2269 needed = 0;
2270 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
2271 ok(status == Ok, "status %d\n", status);
2272 expect(20, needed);
2273
2274 status = GdipCreateRegionRgnData(buf, needed, &region2);
2275 ok(status == Ok, "status %d\n", status);
2276
2277 ret = FALSE;
2278 status = GdipIsEmptyRegion(region2, graphics, &ret);
2279 ok(status == Ok, "status %d\n", status);
2280 ok(ret, "got %d\n", ret);
2281 GdipDeleteRegion(region2);
2282
2283 GdipDeleteGraphics(graphics);
2284 GdipDeleteRegion(region);
2285 ReleaseDC(0, hdc);
2286 }
2287
2288 START_TEST(region)
2289 {
2290 struct GdiplusStartupInput gdiplusStartupInput;
2291 ULONG_PTR gdiplusToken;
2292 HMODULE hmsvcrt;
2293 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
2294
2295 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
2296 hmsvcrt = LoadLibraryA("msvcrt");
2297 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
2298 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
2299
2300 gdiplusStartupInput.GdiplusVersion = 1;
2301 gdiplusStartupInput.DebugEventCallback = NULL;
2302 gdiplusStartupInput.SuppressBackgroundThread = 0;
2303 gdiplusStartupInput.SuppressExternalCodecs = 0;
2304
2305 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
2306
2307 test_getregiondata();
2308 test_isinfinite();
2309 test_isempty();
2310 test_combinereplace();
2311 test_fromhrgn();
2312 test_gethrgn();
2313 test_isequal();
2314 test_translate();
2315 test_transform();
2316 test_scans();
2317 test_getbounds();
2318 test_isvisiblepoint();
2319 test_isvisiblerect();
2320 test_excludeinfinite();
2321 test_GdipCreateRegionRgnData();
2322
2323 GdiplusShutdown(gdiplusToken);
2324 }