2 * Unit test suite for gdiplus regions
4 * Copyright (C) 2008 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
26 #define RGNDATA_RECT 0x10000000
27 #define RGNDATA_PATH 0x10000001
28 #define RGNDATA_EMPTY_RECT 0x10000002
29 #define RGNDATA_INFINITE_RECT 0x10000003
31 #define RGNDATA_MAGIC 0xdbc01001
32 #define RGNDATA_MAGIC2 0xdbc01002
34 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
36 #define expect_magic(value) ok(*value == RGNDATA_MAGIC || *value == RGNDATA_MAGIC2, "Expected a known magic value, got %8x\n", *value)
38 #define expect_dword(value, expected) ok(*(value) == expected, "expected %08x got %08x\n", expected, *(value))
40 static inline void expect_float(DWORD *value, FLOAT expected)
42 FLOAT valuef = *(FLOAT*)value;
43 ok(valuef == expected, "expected %f got %f\n", expected, valuef);
46 /* We get shorts back, not INTs like a GpPoint */
47 typedef struct RegionDataPoint
52 static void test_getregiondata(void)
55 GpRegion *region, *region2;
56 RegionDataPoint *point;
62 memset(buf, 0xee, sizeof(buf));
64 status = GdipCreateRegion(®ion);
65 ok(status == Ok, "status %08x\n", status);
67 status = GdipGetRegionDataSize(region, &needed);
68 ok(status == Ok, "status %08x\n", status);
70 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
71 ok(status == Ok, "status %08x\n", status);
73 expect_dword(buf, 12);
74 trace("buf[1] = %08x\n", buf[1]);
75 expect_magic((DWORD*)(buf + 2));
76 expect_dword(buf + 3, 0);
77 expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
79 status = GdipSetEmpty(region);
80 ok(status == Ok, "status %08x\n", status);
81 status = GdipGetRegionDataSize(region, &needed);
82 ok(status == Ok, "status %08x\n", status);
84 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
85 ok(status == Ok, "status %08x\n", status);
87 expect_dword(buf, 12);
88 trace("buf[1] = %08x\n", buf[1]);
89 expect_magic((DWORD*)(buf + 2));
90 expect_dword(buf + 3, 0);
91 expect_dword(buf + 4, RGNDATA_EMPTY_RECT);
93 status = GdipSetInfinite(region);
94 ok(status == Ok, "status %08x\n", status);
95 status = GdipGetRegionDataSize(region, &needed);
96 ok(status == Ok, "status %08x\n", status);
98 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
99 ok(status == Ok, "status %08x\n", status);
101 expect_dword(buf, 12);
102 trace("buf[1] = %08x\n", buf[1]);
103 expect_magic((DWORD*)(buf + 2));
104 expect_dword(buf + 3, 0);
105 expect_dword(buf + 4, RGNDATA_INFINITE_RECT);
107 status = GdipDeleteRegion(region);
108 ok(status == Ok, "status %08x\n", status);
114 status = GdipCreateRegionRectI(&rect, ®ion);
115 ok(status == Ok, "status %08x\n", status);
116 status = GdipGetRegionDataSize(region, &needed);
117 ok(status == Ok, "status %08x\n", status);
119 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
120 ok(status == Ok, "status %08x\n", status);
122 expect_dword(buf, 28);
123 trace("buf[1] = %08x\n", buf[1]);
124 expect_magic((DWORD*)(buf + 2));
125 expect_dword(buf + 3, 0);
126 expect_dword(buf + 4, RGNDATA_RECT);
127 expect_float(buf + 5, 10.0);
128 expect_float(buf + 6, 20.0);
129 expect_float(buf + 7, 100.0);
130 expect_float(buf + 8, 200.0);
136 status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
137 ok(status == Ok, "status %08x\n", status);
142 status = GdipCombineRegionRectI(region, &rect, CombineModeXor);
143 ok(status == Ok, "status %08x\n", status);
149 status = GdipCreateRegionRectI(&rect, ®ion2);
150 ok(status == Ok, "status %08x\n", status);
155 status = GdipCombineRegionRectI(region2, &rect, CombineModeUnion);
156 ok(status == Ok, "status %08x\n", status);
158 status = GdipCombineRegionRegion(region, region2, CombineModeComplement);
159 ok(status == Ok, "status %08x\n", status);
165 status = GdipCombineRegionRectI(region, &rect, CombineModeExclude);
166 ok(status == Ok, "status %08x\n", status);
168 status = GdipGetRegionDataSize(region, &needed);
169 ok(status == Ok, "status %08x\n", status);
171 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
172 ok(status == Ok, "status %08x\n", status);
174 expect_dword(buf, 148);
175 trace("buf[1] = %08x\n", buf[1]);
176 expect_magic((DWORD*)(buf + 2));
177 expect_dword(buf + 3, 10);
178 expect_dword(buf + 4, CombineModeExclude);
179 expect_dword(buf + 5, CombineModeComplement);
180 expect_dword(buf + 6, CombineModeXor);
181 expect_dword(buf + 7, CombineModeIntersect);
182 expect_dword(buf + 8, RGNDATA_RECT);
183 expect_float(buf + 9, 10.0);
184 expect_float(buf + 10, 20.0);
185 expect_float(buf + 11, 100.0);
186 expect_float(buf + 12, 200.0);
187 expect_dword(buf + 13, RGNDATA_RECT);
188 expect_float(buf + 14, 50.0);
189 expect_float(buf + 15, 30.0);
190 expect_float(buf + 16, 10.0);
191 expect_float(buf + 17, 20.0);
192 expect_dword(buf + 18, RGNDATA_RECT);
193 expect_float(buf + 19, 100.0);
194 expect_float(buf + 20, 300.0);
195 expect_float(buf + 21, 30.0);
196 expect_float(buf + 22, 50.0);
197 expect_dword(buf + 23, CombineModeUnion);
198 expect_dword(buf + 24, RGNDATA_RECT);
199 expect_float(buf + 25, 200.0);
200 expect_float(buf + 26, 100.0);
201 expect_float(buf + 27, 133.0);
202 expect_float(buf + 28, 266.0);
203 expect_dword(buf + 29, RGNDATA_RECT);
204 expect_float(buf + 30, 20.0);
205 expect_float(buf + 31, 10.0);
206 expect_float(buf + 32, 40.0);
207 expect_float(buf + 33, 66.0);
208 expect_dword(buf + 34, RGNDATA_RECT);
209 expect_float(buf + 35, 400.0);
210 expect_float(buf + 36, 500.0);
211 expect_float(buf + 37, 22.0);
212 expect_float(buf + 38, 55.0);
214 status = GdipDeleteRegion(region2);
215 ok(status == Ok, "status %08x\n", status);
216 status = GdipDeleteRegion(region);
217 ok(status == Ok, "status %08x\n", status);
221 status = GdipCreatePath(FillModeAlternate, &path);
222 ok(status == Ok, "status %08x\n", status);
223 GdipAddPathRectangle(path, 12.5, 13.0, 14.0, 15.0);
225 status = GdipCreateRegionPath(path, ®ion);
226 ok(status == Ok, "status %08x\n", status);
227 status = GdipGetRegionDataSize(region, &needed);
228 ok(status == Ok, "status %08x\n", status);
230 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
231 ok(status == Ok, "status %08x\n", status);
233 expect_dword(buf, 64);
234 trace("buf[1] = %08x\n", buf[1]);
235 expect_magic((DWORD*)(buf + 2));
236 expect_dword(buf + 3, 0);
237 expect_dword(buf + 4, RGNDATA_PATH);
238 expect_dword(buf + 5, 0x00000030);
239 expect_magic((DWORD*)(buf + 6));
240 expect_dword(buf + 7, 0x00000004);
241 expect_dword(buf + 8, 0x00000000);
242 expect_float(buf + 9, 12.5);
243 expect_float(buf + 10, 13.0);
244 expect_float(buf + 11, 26.5);
245 expect_float(buf + 12, 13.0);
246 expect_float(buf + 13, 26.5);
247 expect_float(buf + 14, 28.0);
248 expect_float(buf + 15, 12.5);
249 expect_float(buf + 16, 28.0);
250 expect_dword(buf + 17, 0x81010100);
257 status = GdipCombineRegionRectI(region, &rect, CombineModeIntersect);
258 ok(status == Ok, "status %08x\n", status);
259 status = GdipGetRegionDataSize(region, &needed);
260 ok(status == Ok, "status %08x\n", status);
262 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
263 ok(status == Ok, "status %08x\n", status);
265 expect_dword(buf, 88);
266 trace("buf[1] = %08x\n", buf[1]);
267 expect_magic((DWORD*)(buf + 2));
268 expect_dword(buf + 3, 2);
269 expect_dword(buf + 4, CombineModeIntersect);
270 expect_dword(buf + 5, RGNDATA_PATH);
271 expect_dword(buf + 6, 0x00000030);
272 expect_magic((DWORD*)(buf + 7));
273 expect_dword(buf + 8, 0x00000004);
274 expect_dword(buf + 9, 0x00000000);
275 expect_float(buf + 10, 12.5);
276 expect_float(buf + 11, 13.0);
277 expect_float(buf + 12, 26.5);
278 expect_float(buf + 13, 13.0);
279 expect_float(buf + 14, 26.5);
280 expect_float(buf + 15, 28.0);
281 expect_float(buf + 16, 12.5);
282 expect_float(buf + 17, 28.0);
283 expect_dword(buf + 18, 0x81010100);
284 expect_dword(buf + 19, RGNDATA_RECT);
285 expect_float(buf + 20, 50.0);
286 expect_float(buf + 21, 30.0);
287 expect_float(buf + 22, 10.0);
288 expect_float(buf + 23, 20.0);
290 status = GdipDeleteRegion(region);
291 ok(status == Ok, "status %08x\n", status);
292 status = GdipDeletePath(path);
293 ok(status == Ok, "status %08x\n", status);
295 /* Test an empty path */
296 status = GdipCreatePath(FillModeAlternate, &path);
298 status = GdipCreateRegionPath(path, ®ion);
300 status = GdipGetRegionDataSize(region, &needed);
303 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
306 expect_dword(buf, 28);
307 trace("buf[1] = %08x\n", buf[1]);
308 expect_magic((DWORD*)(buf + 2));
309 expect_dword(buf + 3, 0);
310 expect_dword(buf + 4, RGNDATA_PATH);
312 /* Second signature for pathdata */
313 expect_dword(buf + 5, 12);
314 expect_magic((DWORD*)(buf + 6));
315 expect_dword(buf + 7, 0);
316 expect_dword(buf + 8, 0x00004000);
318 status = GdipDeleteRegion(region);
321 /* Test a simple triangle of INTs */
322 status = GdipAddPathLine(path, 5, 6, 7, 8);
324 status = GdipAddPathLine(path, 8, 1, 5, 6);
326 status = GdipClosePathFigure(path);
328 status = GdipCreateRegionPath(path, ®ion);
330 status = GdipGetRegionDataSize(region, &needed);
333 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
336 expect_dword(buf, 48);
337 trace("buf[1] = %08x\n", buf[1]);
338 expect_magic((DWORD*)(buf + 2));
339 expect_dword(buf + 3 , 0);
340 expect_dword(buf + 4 , RGNDATA_PATH);
342 expect_dword(buf + 5, 32);
343 expect_magic((DWORD*)(buf + 6));
344 expect_dword(buf + 7, 4);
345 expect_dword(buf + 8, 0x00004000); /* ?? */
347 point = (RegionDataPoint*)buf + 9;
348 expect(5, point[0].X);
349 expect(6, point[0].Y);
350 expect(7, point[1].X); /* buf + 10 */
351 expect(8, point[1].Y);
352 expect(8, point[2].X); /* buf + 11 */
353 expect(1, point[2].Y);
354 expect(5, point[3].X); /* buf + 12 */
355 expect(6, point[3].Y);
356 expect_dword(buf + 13, 0x81010100); /* 0x01010100 if we don't close the path */
358 status = GdipDeletePath(path);
360 status = GdipDeleteRegion(region);
363 /* Test a floating-point triangle */
364 status = GdipCreatePath(FillModeAlternate, &path);
366 status = GdipAddPathLine(path, 5.6, 6.2, 7.2, 8.9);
368 status = GdipAddPathLine(path, 8.1, 1.6, 5.6, 6.2);
370 status = GdipCreateRegionPath(path, ®ion);
372 status = GdipGetRegionDataSize(region, &needed);
375 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
378 expect_dword(buf, 64);
379 trace("buf[1] = %08x\n", buf[1]);
380 expect_magic((DWORD*)(buf + 2));
381 expect_dword(buf + 3, 0);
382 expect_dword(buf + 4, RGNDATA_PATH);
384 expect_dword(buf + 5, 48);
385 expect_magic((DWORD*)(buf + 6));
386 expect_dword(buf + 7, 4);
387 expect_dword(buf + 8, 0);
388 expect_float(buf + 9, 5.6);
389 expect_float(buf + 10, 6.2);
390 expect_float(buf + 11, 7.2);
391 expect_float(buf + 12, 8.9);
392 expect_float(buf + 13, 8.1);
393 expect_float(buf + 14, 1.6);
394 expect_float(buf + 15, 5.6);
395 expect_float(buf + 16, 6.2);
397 status = GdipDeletePath(path);
399 status = GdipDeleteRegion(region);
402 /* Test for a path with > 4 points, and CombineRegionPath */
403 GdipCreatePath(FillModeAlternate, &path);
404 status = GdipAddPathLine(path, 50, 70.2, 60, 102.8);
406 status = GdipAddPathLine(path, 55.4, 122.4, 40.4, 60.2);
408 status = GdipAddPathLine(path, 45.6, 20.2, 50, 70.2);
414 status = GdipCreateRegionRectI(&rect, ®ion);
416 status = GdipCombineRegionPath(region, path, CombineModeUnion);
419 status = GdipGetRegionDataSize(region, &needed);
422 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
425 expect_dword(buf, 108);
426 trace("buf[1] = %08x\n", buf[1]);
427 expect_magic((DWORD*)(buf + 2));
428 expect_dword(buf + 3, 2);
429 expect_dword(buf + 4, CombineModeUnion);
430 expect_dword(buf + 5, RGNDATA_RECT);
431 expect_float(buf + 6, 20);
432 expect_float(buf + 7, 25);
433 expect_float(buf + 8, 60);
434 expect_float(buf + 9, 120);
435 expect_dword(buf + 10, RGNDATA_PATH);
437 expect_dword(buf + 11, 68);
438 expect_magic((DWORD*)(buf + 12));
439 expect_dword(buf + 13, 6);
440 expect_float(buf + 14, 0x0);
442 expect_float(buf + 15, 50);
443 expect_float(buf + 16, 70.2);
444 expect_float(buf + 17, 60);
445 expect_float(buf + 18, 102.8);
446 expect_float(buf + 19, 55.4);
447 expect_float(buf + 20, 122.4);
448 expect_float(buf + 21, 40.4);
449 expect_float(buf + 22, 60.2);
450 expect_float(buf + 23, 45.6);
451 expect_float(buf + 24, 20.2);
452 expect_float(buf + 25, 50);
453 expect_float(buf + 26, 70.2);
454 expect_dword(buf + 27, 0x01010100);
455 expect_dword(buf + 28, 0x00000101);
457 status = GdipDeletePath(path);
459 status = GdipDeleteRegion(region);
463 static void test_isinfinite(void)
467 GpGraphics *graphics = NULL;
472 status = GdipCreateFromHDC(hdc, &graphics);
474 GdipCreateRegion(®ion);
476 GdipCreateMatrix2(3.0, 0.0, 0.0, 1.0, 20.0, 30.0, &m);
479 status = GdipIsInfiniteRegion(NULL, NULL, NULL);
480 expect(InvalidParameter, status);
481 status = GdipIsInfiniteRegion(region, NULL, NULL);
482 expect(InvalidParameter, status);
483 status = GdipIsInfiniteRegion(NULL, graphics, NULL);
484 expect(InvalidParameter, status);
485 status = GdipIsInfiniteRegion(NULL, NULL, &res);
486 expect(InvalidParameter, status);
487 status = GdipIsInfiniteRegion(region, NULL, &res);
488 expect(InvalidParameter, status);
491 status = GdipIsInfiniteRegion(region, graphics, &res);
495 /* after world transform */
496 status = GdipSetWorldTransform(graphics, m);
500 status = GdipIsInfiniteRegion(region, graphics, &res);
505 GdipDeleteRegion(region);
506 GdipDeleteGraphics(graphics);
510 static void test_isempty(void)
514 GpGraphics *graphics = NULL;
518 status = GdipCreateFromHDC(hdc, &graphics);
520 GdipCreateRegion(®ion);
523 status = GdipIsEmptyRegion(NULL, NULL, NULL);
524 expect(InvalidParameter, status);
525 status = GdipIsEmptyRegion(region, NULL, NULL);
526 expect(InvalidParameter, status);
527 status = GdipIsEmptyRegion(NULL, graphics, NULL);
528 expect(InvalidParameter, status);
529 status = GdipIsEmptyRegion(NULL, NULL, &res);
530 expect(InvalidParameter, status);
531 status = GdipIsEmptyRegion(region, NULL, &res);
532 expect(InvalidParameter, status);
534 /* default is infinite */
536 status = GdipIsEmptyRegion(region, graphics, &res);
540 status = GdipSetEmpty(region);
544 status = GdipIsEmptyRegion(region, graphics, &res);
548 GdipDeleteRegion(region);
549 GdipDeleteGraphics(graphics);
553 static void test_combinereplace(void)
561 rectf.X = rectf.Y = 0.0;
562 rectf.Width = rectf.Height = 100.0;
564 status = GdipCreateRegionRect(&rectf, ®ion);
567 /* replace with the same rectangle */
568 status = GdipCombineRegionRect(region, &rectf,CombineModeReplace);
571 status = GdipGetRegionDataSize(region, &needed);
573 todo_wine expect(36, needed);
574 status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed);
576 todo_wine expect(36, needed);
577 todo_wine expect_dword(buf, 28);
578 trace("buf[1] = %08x\n", buf[1]);
579 expect_magic((DWORD*)(buf + 2));
580 todo_wine expect_dword(buf + 3, 0);
581 todo_wine expect_dword(buf + 4, RGNDATA_RECT);
583 GdipDeleteRegion(region);
588 struct GdiplusStartupInput gdiplusStartupInput;
589 ULONG_PTR gdiplusToken;
591 gdiplusStartupInput.GdiplusVersion = 1;
592 gdiplusStartupInput.DebugEventCallback = NULL;
593 gdiplusStartupInput.SuppressBackgroundThread = 0;
594 gdiplusStartupInput.SuppressExternalCodecs = 0;
596 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
598 test_getregiondata();
601 test_combinereplace();
603 GdiplusShutdown(gdiplusToken);