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