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