gdiplus: Implement GdipSetInfinite.
[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
26 #define RGNDATA_RECT            0x10000000
27 #define RGNDATA_PATH            0x10000001
28 #define RGNDATA_EMPTY_RECT      0x10000002
29 #define RGNDATA_INFINITE_RECT   0x10000003
30
31 #define RGNDATA_MAGIC           0xdbc01001
32 #define RGNDATA_MAGIC2          0xdbc01002
33
34 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
35
36 #define expect_magic(value) ok(*value == RGNDATA_MAGIC || *value == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *value)
37
38 static inline void expect_dword(DWORD *value, DWORD expected)
39 {
40     ok(*value == expected, "expected %08x got %08x\n", expected, *value);
41 }
42
43 static inline void expect_float(DWORD *value, FLOAT expected)
44 {
45     FLOAT valuef = *(FLOAT*)value;
46     ok(valuef == expected, "expected %f got %f\n", expected, valuef);
47 }
48
49 /* We get shorts back, not INTs like a GpPoint */
50 typedef struct RegionDataPoint
51 {
52     short X, Y;
53 } RegionDataPoint;
54
55 static void test_getregiondata(void)
56 {
57     GpStatus status;
58     GpRegion *region, *region2;
59     RegionDataPoint *point;
60     UINT needed;
61     DWORD buf[100];
62     GpRect rect;
63     GpPath *path;
64
65     memset(buf, 0xee, sizeof(buf));
66
67     status = GdipCreateRegion(&region);
68     ok(status == Ok, "status %08x\n", status);
69
70 todo_wine
71 {
72     status = GdipGetRegionDataSize(region, &needed);
73     ok(status == Ok, "status %08x\n", status);
74     expect(20, needed);
75     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
76     ok(status == Ok, "status %08x\n", status);
77     expect(20, needed);
78     expect_dword(buf, 12);
79     trace("buf[1] = %08x\n", buf[1]);
80     expect_magic((DWORD*)(buf + 2));
81     expect_dword(buf + 3, 0);
82     expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
83
84     status = GdipSetEmpty(region);
85 }
86     ok(status == Ok, "status %08x\n", status);
87 todo_wine
88 {
89     status = GdipGetRegionDataSize(region, &needed);
90     ok(status == Ok, "status %08x\n", status);
91     expect(20, needed);
92     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
93     ok(status == Ok, "status %08x\n", status);
94     expect(20, needed);
95     expect_dword(buf, 12);
96     trace("buf[1] = %08x\n", buf[1]);
97     expect_magic((DWORD*)(buf + 2));
98     expect_dword(buf + 3, 0);
99     expect_dword(buf + 4, RGNDATA_EMPTY_RECT);
100 }
101
102     status = GdipSetInfinite(region);
103     ok(status == Ok, "status %08x\n", status);
104     status = GdipGetRegionDataSize(region, &needed);
105 todo_wine
106 {
107     ok(status == Ok, "status %08x\n", status);
108     expect(20, needed);
109     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
110     ok(status == Ok, "status %08x\n", status);
111     expect(20, needed);
112     expect_dword(buf, 12);
113     trace("buf[1] = %08x\n", buf[1]);
114     expect_magic((DWORD*)(buf + 2));
115     expect_dword(buf + 3, 0);
116     expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
117 }
118
119     status = GdipDeleteRegion(region);
120     ok(status == Ok, "status %08x\n", status);
121
122     rect.X = 10;
123     rect.Y = 20;
124     rect.Width = 100;
125     rect.Height = 200;
126 todo_wine
127 {
128     status = GdipCreateRegionRectI(&rect, &region);
129     ok(status == Ok, "status %08x\n", status);
130     status = GdipGetRegionDataSize(region, &needed);
131     ok(status == Ok, "status %08x\n", status);
132     expect(36, needed);
133     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
134     ok(status == Ok, "status %08x\n", status);
135     expect(36, needed);
136     expect_dword(buf, 28);
137     trace("buf[1] = %08x\n", buf[1]);
138     expect_magic((DWORD*)(buf + 2));
139     expect_dword(buf + 3, 0);
140     expect_dword(buf + 4, RGNDATA_RECT);
141     expect_float(buf + 5, 10.0);
142     expect_float(buf + 6, 20.0);
143     expect_float(buf + 7, 100.0);
144     expect_float(buf + 8, 200.0);
145
146     rect.X = 50;
147     rect.Y = 30;
148     rect.Width = 10;
149     rect.Height = 20;
150     status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
151     ok(status == Ok, "status %08x\n", status);
152     rect.X = 100;
153     rect.Y = 300;
154     rect.Width = 30;
155     rect.Height = 50;
156     status = GdipCombineRegionRectI(region, &rect, CombineModeXor);
157     ok(status == Ok, "status %08x\n", status);
158
159     rect.X = 200;
160     rect.Y = 100;
161     rect.Width = 133;
162     rect.Height = 266;
163     status = GdipCreateRegionRectI(&rect, &region2);
164     ok(status == Ok, "status %08x\n", status);
165     rect.X = 20;
166     rect.Y = 10;
167     rect.Width = 40;
168     rect.Height = 66;
169     status = GdipCombineRegionRectI(region2, &rect, CombineModeUnion);
170     ok(status == Ok, "status %08x\n", status);
171
172     status = GdipCombineRegionRegion(region, region2, CombineModeComplement);
173     ok(status == Ok, "status %08x\n", status);
174
175     rect.X = 400;
176     rect.Y = 500;
177     rect.Width = 22;
178     rect.Height = 55;
179     status = GdipCombineRegionRectI(region, &rect, CombineModeExclude);
180     ok(status == Ok, "status %08x\n", status);
181
182     status = GdipGetRegionDataSize(region, &needed);
183     ok(status == Ok, "status %08x\n", status);
184     expect(156, needed);
185     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
186     ok(status == Ok, "status %08x\n", status);
187     expect(156, needed);
188     expect_dword(buf, 148);
189     trace("buf[1] = %08x\n", buf[1]);
190     expect_magic((DWORD*)(buf + 2));
191     expect_dword(buf + 3, 10);
192     expect_dword(buf + 4, CombineModeExclude);
193     expect_dword(buf + 5, CombineModeComplement);
194     expect_dword(buf + 6, CombineModeXor);
195     expect_dword(buf + 7, CombineModeIntersect);
196     expect_dword(buf + 8, RGNDATA_RECT);
197     expect_float(buf + 9, 10.0);
198     expect_float(buf + 10, 20.0);
199     expect_float(buf + 11, 100.0);
200     expect_float(buf + 12, 200.0);
201     expect_dword(buf + 13, RGNDATA_RECT);
202     expect_float(buf + 14, 50.0);
203     expect_float(buf + 15, 30.0);
204     expect_float(buf + 16, 10.0);
205     expect_float(buf + 17, 20.0);
206     expect_dword(buf + 18, RGNDATA_RECT);
207     expect_float(buf + 19, 100.0);
208     expect_float(buf + 20, 300.0);
209     expect_float(buf + 21, 30.0);
210     expect_float(buf + 22, 50.0);
211     expect_dword(buf + 23, CombineModeUnion);
212     expect_dword(buf + 24, RGNDATA_RECT);
213     expect_float(buf + 25, 200.0);
214     expect_float(buf + 26, 100.0);
215     expect_float(buf + 27, 133.0);
216     expect_float(buf + 28, 266.0);
217     expect_dword(buf + 29, RGNDATA_RECT);
218     expect_float(buf + 30, 20.0);
219     expect_float(buf + 31, 10.0);
220     expect_float(buf + 32, 40.0);
221     expect_float(buf + 33, 66.0);
222     expect_dword(buf + 34, RGNDATA_RECT);
223     expect_float(buf + 35, 400.0);
224     expect_float(buf + 36, 500.0);
225     expect_float(buf + 37, 22.0);
226     expect_float(buf + 38, 55.0);
227
228     status = GdipDeleteRegion(region2);
229     ok(status == Ok, "status %08x\n", status);
230     status = GdipDeleteRegion(region);
231     ok(status == Ok, "status %08x\n", status);
232 }
233
234     /* Try some paths */
235
236     status = GdipCreatePath(FillModeAlternate, &path);
237     ok(status == Ok, "status %08x\n", status);
238 todo_wine
239 {
240     GdipAddPathRectangle(path, 12.5, 13.0, 14.0, 15.0);
241
242     status = GdipCreateRegionPath(path, &region);
243     ok(status == Ok, "status %08x\n", status);
244     status = GdipGetRegionDataSize(region, &needed);
245     ok(status == Ok, "status %08x\n", status);
246     expect(72, needed);
247     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
248     ok(status == Ok, "status %08x\n", status);
249     expect(72, needed);
250     expect_dword(buf, 64);
251     trace("buf[1] = %08x\n", buf[1]);
252     expect_magic((DWORD*)(buf + 2));
253     expect_dword(buf + 3, 0);
254     expect_dword(buf + 4, RGNDATA_PATH);
255     expect_dword(buf + 5, 0x00000030);
256     expect_magic((DWORD*)(buf + 6));
257     expect_dword(buf + 7, 0x00000004);
258     expect_dword(buf + 8, 0x00000000);
259     expect_float(buf + 9, 12.5);
260     expect_float(buf + 10, 13.0);
261     expect_float(buf + 11, 26.5);
262     expect_float(buf + 12, 13.0);
263     expect_float(buf + 13, 26.5);
264     expect_float(buf + 14, 28.0);
265     expect_float(buf + 15, 12.5);
266     expect_float(buf + 16, 28.0);
267     expect_dword(buf + 17, 0x81010100);
268
269
270     rect.X = 50;
271     rect.Y = 30;
272     rect.Width = 10;
273     rect.Height = 20;
274     status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
275     ok(status == Ok, "status %08x\n", status);
276     status = GdipGetRegionDataSize(region, &needed);
277     ok(status == Ok, "status %08x\n", status);
278     expect(96, needed);
279     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
280     ok(status == Ok, "status %08x\n", status);
281     expect(96, needed);
282     expect_dword(buf, 88);
283     trace("buf[1] = %08x\n", buf[1]);
284     expect_magic((DWORD*)(buf + 2));
285     expect_dword(buf + 3, 2);
286     expect_dword(buf + 4, CombineModeIntersect);
287     expect_dword(buf + 5, RGNDATA_PATH);
288     expect_dword(buf + 6, 0x00000030);
289     expect_magic((DWORD*)(buf + 7));
290     expect_dword(buf + 8, 0x00000004);
291     expect_dword(buf + 9, 0x00000000);
292     expect_float(buf + 10, 12.5);
293     expect_float(buf + 11, 13.0);
294     expect_float(buf + 12, 26.5);
295     expect_float(buf + 13, 13.0);
296     expect_float(buf + 14, 26.5);
297     expect_float(buf + 15, 28.0);
298     expect_float(buf + 16, 12.5);
299     expect_float(buf + 17, 28.0);
300     expect_dword(buf + 18, 0x81010100);
301     expect_dword(buf + 19, RGNDATA_RECT);
302     expect_float(buf + 20, 50.0);
303     expect_float(buf + 21, 30.0);
304     expect_float(buf + 22, 10.0);
305     expect_float(buf + 23, 20.0);
306
307     status = GdipDeleteRegion(region);
308     ok(status == Ok, "status %08x\n", status);
309 }
310     status = GdipDeletePath(path);
311     ok(status == Ok, "status %08x\n", status);
312
313     /* Test an empty path */
314     status = GdipCreatePath(FillModeAlternate, &path);
315     expect(Ok, status);
316 todo_wine
317 {
318     status = GdipCreateRegionPath(path, &region);
319     expect(Ok, status);
320     status = GdipGetRegionDataSize(region, &needed);
321     expect(Ok, status);
322     expect(36, needed);
323     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
324     expect(Ok, status);
325     expect(36, needed);
326     expect_dword(buf, 28);
327     trace("buf[1] = %08x\n", buf[1]);
328     expect_magic((DWORD*)(buf + 2));
329     expect_dword(buf + 3, 0);
330     expect_dword(buf + 4, RGNDATA_PATH);
331
332     /* Second signature for pathdata */
333     expect_dword(buf + 5, 12);
334     expect_magic((DWORD*)(buf + 6));
335     expect_dword(buf + 7, 0);
336     expect_dword(buf + 8, 0x00004000);
337
338     status = GdipDeleteRegion(region);
339     expect(Ok, status);
340 }
341
342     /* Test a simple triangle of INTs */
343     status = GdipAddPathLine(path, 5, 6, 7, 8);
344     expect(Ok, status);
345     status = GdipAddPathLine(path, 8, 1, 5, 6);
346     expect(Ok, status);
347     status = GdipClosePathFigure(path);
348     expect(Ok, status);
349 todo_wine
350 {
351     status = GdipCreateRegionPath(path, &region);
352     expect(Ok, status);
353     status = GdipGetRegionDataSize(region, &needed);
354     expect(Ok, status);
355     expect(56, needed);
356     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
357     expect(Ok, status);
358     expect(56, needed);
359     expect_dword(buf, 48);
360     trace("buf[1] = %08x\n", buf[1]);
361     expect_magic((DWORD*)(buf + 2));
362     expect_dword(buf + 3 , 0);
363     expect_dword(buf + 4 , RGNDATA_PATH);
364
365     expect_dword(buf + 5, 32);
366     expect_magic((DWORD*)(buf + 6));
367     expect_dword(buf + 7, 4);
368     expect_dword(buf + 8, 0x00004000); /* ?? */
369
370     point = (RegionDataPoint*)buf + 9;
371     expect(5, point[0].X);
372     expect(6, point[0].Y);
373     expect(7, point[1].X); /* buf + 10 */
374     expect(8, point[1].Y);
375     expect(8, point[2].X); /* buf + 11 */
376     expect(1, point[2].Y);
377     expect(5, point[3].X); /* buf + 12 */
378     expect(6, point[3].Y);
379     expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */
380 }
381     status = GdipDeletePath(path);
382     expect(Ok, status);
383     status = GdipDeleteRegion(region);
384 todo_wine
385     expect(Ok, status);
386
387     /* Test a floating-point triangle */
388     status = GdipCreatePath(FillModeAlternate, &path);
389     expect(Ok, status);
390     status = GdipAddPathLine(path, 5.6, 6.2, 7.2, 8.9);
391     expect(Ok, status);
392     status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2);
393     expect(Ok, status);
394 todo_wine
395 {
396     status = GdipCreateRegionPath(path, &region);
397     expect(Ok, status);
398     status = GdipGetRegionDataSize(region, &needed);
399     expect(Ok, status);
400     expect(72, needed);
401     status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
402     expect(Ok, status);
403     expect(72, needed);
404     expect_dword(buf, 64);
405     trace("buf[1] = %08x\n", buf[1]);
406     expect_magic((DWORD*)(buf + 2));
407     expect_dword(buf + 3, 0);
408     expect_dword(buf + 4, RGNDATA_PATH);
409
410     expect_dword(buf + 5, 48);
411     expect_magic((DWORD*)(buf + 6));
412     expect_dword(buf + 7, 4);
413     expect_dword(buf + 8, 0);
414     expect_float(buf + 9, 5.6);
415     expect_float(buf + 10, 6.2);
416     expect_float(buf + 11, 7.2);
417     expect_float(buf + 12, 8.9);
418     expect_float(buf + 13, 8.1);
419     expect_float(buf + 14, 1.6);
420     expect_float(buf + 15, 5.6);
421     expect_float(buf + 16, 6.2);
422 }
423
424     status = GdipDeletePath(path);
425     expect(Ok, status);
426     status = GdipDeleteRegion(region);
427 todo_wine
428     expect(Ok, status);
429 }
430
431 START_TEST(region)
432 {
433     struct GdiplusStartupInput gdiplusStartupInput;
434     ULONG_PTR gdiplusToken;
435
436     gdiplusStartupInput.GdiplusVersion              = 1;
437     gdiplusStartupInput.DebugEventCallback          = NULL;
438     gdiplusStartupInput.SuppressBackgroundThread    = 0;
439     gdiplusStartupInput.SuppressExternalCodecs      = 0;
440
441     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
442
443     test_getregiondata();
444
445     GdiplusShutdown(gdiplusToken);
446
447 }