[NTOS:KE/x64] Handle NMI vs swapgs race condition
[reactos.git] / modules / rostests / winetests / gdiplus / pathiterator.c
1 /*
2 * Unit test suite for pathiterator
3 *
4 * Copyright (C) 2008 Nikolay Sivov
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 "objbase.h"
22 #include "gdiplus.h"
23 #include "wine/test.h"
24
25 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
26
27 static void test_constructor_destructor(void)
28 {
29 GpPath *path;
30 GpPathIterator *iter;
31 GpStatus stat;
32
33 GdipCreatePath(FillModeAlternate, &path);
34 GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
35
36 /* NULL args */
37 stat = GdipCreatePathIter(NULL, NULL);
38 expect(InvalidParameter, stat);
39 iter = NULL;
40 stat = GdipCreatePathIter(&iter, NULL);
41 expect(Ok, stat);
42 ok(iter != NULL, "Expected iterator to be created\n");
43 GdipDeletePathIter(iter);
44 stat = GdipCreatePathIter(NULL, path);
45 expect(InvalidParameter, stat);
46 stat = GdipDeletePathIter(NULL);
47 expect(InvalidParameter, stat);
48
49 /* valid args */
50 stat = GdipCreatePathIter(&iter, path);
51 expect(Ok, stat);
52
53 GdipDeletePathIter(iter);
54 GdipDeletePath(path);
55 }
56
57 static void test_hascurve(void)
58 {
59 GpPath *path;
60 GpPathIterator *iter;
61 GpStatus stat;
62 BOOL hasCurve;
63
64 GdipCreatePath(FillModeAlternate, &path);
65 GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
66
67 stat = GdipCreatePathIter(&iter, path);
68 expect(Ok, stat);
69
70 /* NULL args
71 BOOL out argument is local in wrapper class method,
72 so it always has not-NULL address */
73 stat = GdipPathIterHasCurve(NULL, &hasCurve);
74 expect(InvalidParameter, stat);
75
76 /* valid args */
77 stat = GdipPathIterHasCurve(iter, &hasCurve);
78 expect(Ok, stat);
79 expect(FALSE, hasCurve);
80
81 GdipDeletePathIter(iter);
82
83 stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0);
84 expect(Ok, stat);
85
86 stat = GdipCreatePathIter(&iter, path);
87 expect(Ok, stat);
88
89 stat = GdipPathIterHasCurve(iter, &hasCurve);
90 expect(Ok, stat);
91 expect(TRUE, hasCurve);
92
93 GdipDeletePathIter(iter);
94 GdipDeletePath(path);
95 }
96
97 static void test_nextmarker(void)
98 {
99 GpPath *path;
100 GpPathIterator *iter;
101 GpStatus stat;
102 INT start, end;
103 INT result;
104
105 /* NULL args
106 BOOL out argument is local in wrapper class method,
107 so it always has not-NULL address */
108 stat = GdipPathIterNextMarker(NULL, &result, NULL, NULL);
109 expect(InvalidParameter, stat);
110 stat = GdipPathIterNextMarker(NULL, &result, &start, NULL);
111 expect(InvalidParameter, stat);
112 stat = GdipPathIterNextMarker(NULL, &result, NULL, &end);
113 expect(InvalidParameter, stat);
114
115 GdipCreatePath(FillModeAlternate, &path);
116 GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
117
118 /* no markers */
119 GdipCreatePathIter(&iter, path);
120 start = end = result = (INT)0xdeadbeef;
121 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
122 expect(Ok, stat);
123 expect(0, start);
124 expect(3, end);
125 expect(4, result);
126 start = end = result = (INT)0xdeadbeef;
127 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
128 expect(Ok, stat);
129 /* start/end remain unchanged */
130 expect((INT)0xdeadbeef, start);
131 expect((INT)0xdeadbeef, end);
132 expect(0, result);
133 GdipDeletePathIter(iter);
134
135 /* one marker */
136 GdipSetPathMarker(path);
137 GdipCreatePathIter(&iter, path);
138 start = end = result = (INT)0xdeadbeef;
139 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
140 expect(Ok, stat);
141 expect(0, start);
142 expect(3, end);
143 expect(4, result);
144 start = end = result = (INT)0xdeadbeef;
145 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
146 expect(Ok, stat);
147 expect((INT)0xdeadbeef, start);
148 expect((INT)0xdeadbeef, end);
149 expect(0, result);
150 GdipDeletePathIter(iter);
151
152 /* two markers */
153 GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
154 GdipSetPathMarker(path);
155 GdipCreatePathIter(&iter, path);
156 start = end = result = (INT)0xdeadbeef;
157 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
158 expect(Ok, stat);
159 expect(0, start);
160 expect(3, end);
161 expect(4, result);
162 start = end = result = (INT)0xdeadbeef;
163 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
164 expect(Ok, stat);
165 expect(4, start);
166 expect(5, end);
167 expect(2, result);
168 start = end = result = (INT)0xdeadbeef;
169 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
170 expect(Ok, stat);
171 expect((INT)0xdeadbeef, start);
172 expect((INT)0xdeadbeef, end);
173 expect(0, result);
174 GdipDeletePathIter(iter);
175
176 GdipDeletePath(path);
177 }
178
179 static void test_nextmarkerpath(void)
180 {
181 GpPath *path, *retpath;
182 GpPathIterator *iter;
183 GpStatus stat;
184 INT result, count;
185
186 GdipCreatePath(FillModeAlternate, &path);
187
188 /* NULL */
189 stat = GdipPathIterNextMarkerPath(NULL, NULL, NULL);
190 expect(InvalidParameter, stat);
191 stat = GdipPathIterNextMarkerPath(NULL, &result, NULL);
192 expect(InvalidParameter, stat);
193 stat = GdipPathIterNextMarkerPath(NULL, &result, path);
194 expect(InvalidParameter, stat);
195
196 GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
197
198 /* no markers */
199 GdipCreatePath(FillModeAlternate, &retpath);
200 GdipCreatePathIter(&iter, path);
201 result = -1;
202 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
203 expect(Ok, stat);
204 expect(4, result);
205 count = -1;
206 GdipGetPointCount(retpath, &count);
207 expect(4, count);
208 result = -1;
209 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
210 expect(Ok, stat);
211 expect(0, result);
212 count = -1;
213 GdipGetPointCount(retpath, &count);
214 expect(4, count);
215 GdipDeletePathIter(iter);
216 GdipDeletePath(retpath);
217
218 /* one marker */
219 GdipSetPathMarker(path);
220 GdipCreatePath(FillModeAlternate, &retpath);
221 GdipCreatePathIter(&iter, path);
222 result = -1;
223 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
224 expect(Ok, stat);
225 expect(4, result);
226 count = -1;
227 GdipGetPointCount(retpath, &count);
228 expect(4, count);
229 result = -1;
230 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
231 expect(Ok, stat);
232 expect(0, result);
233 count = -1;
234 GdipGetPointCount(retpath, &count);
235 expect(4, count);
236 GdipDeletePathIter(iter);
237 GdipDeletePath(retpath);
238
239 /* two markers */
240 GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
241 GdipSetPathMarker(path);
242 GdipCreatePath(FillModeAlternate, &retpath);
243 GdipCreatePathIter(&iter, path);
244 result = -1;
245 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
246 expect(Ok, stat);
247 expect(4, result);
248 result = -1;
249 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
250 expect(Ok, stat);
251 expect(2, result);
252 result = -1;
253 stat = GdipPathIterNextMarkerPath(iter, &result, retpath);
254 expect(Ok, stat);
255 expect(0, result);
256 GdipDeletePathIter(iter);
257 GdipDeletePath(retpath);
258
259 GdipDeletePath(path);
260 }
261
262 static void test_getsubpathcount(void)
263 {
264 GpPath *path;
265 GpPathIterator *iter;
266 GpStatus stat;
267 INT count;
268
269 /* NULL args */
270 stat = GdipPathIterGetSubpathCount(NULL, NULL);
271 expect(InvalidParameter, stat);
272 stat = GdipPathIterGetSubpathCount(NULL, &count);
273 expect(InvalidParameter, stat);
274
275 GdipCreatePath(FillModeAlternate, &path);
276
277 /* empty path */
278 GdipCreatePathIter(&iter, path);
279 stat = GdipPathIterGetSubpathCount(iter, &count);
280 expect(Ok, stat);
281 expect(0, count);
282 GdipDeletePathIter(iter);
283
284 GdipAddPathLine(path, 5.0, 5.0, 100.0, 50.0);
285
286 /* open figure */
287 GdipCreatePathIter(&iter, path);
288 stat = GdipPathIterGetSubpathCount(iter, &count);
289 expect(Ok, stat);
290 expect(1, count);
291 GdipDeletePathIter(iter);
292
293 /* manually start new figure */
294 GdipStartPathFigure(path);
295 GdipAddPathLine(path, 50.0, 50.0, 110.0, 40.0);
296 GdipCreatePathIter(&iter, path);
297 stat = GdipPathIterGetSubpathCount(iter, &count);
298 expect(Ok, stat);
299 expect(2, count);
300 GdipDeletePathIter(iter);
301
302 GdipDeletePath(path);
303 }
304
305 static void test_isvalid(void)
306 {
307 GpPath *path;
308 GpPathIterator *iter;
309 GpStatus stat;
310 BOOL isvalid;
311 INT start, end, result;
312
313 GdipCreatePath(FillModeAlternate, &path);
314
315 /* NULL args */
316 GdipCreatePathIter(&iter, path);
317 stat = GdipPathIterIsValid(NULL, NULL);
318 expect(InvalidParameter, stat);
319 stat = GdipPathIterIsValid(iter, NULL);
320 expect(InvalidParameter, stat);
321 stat = GdipPathIterIsValid(NULL, &isvalid);
322 expect(InvalidParameter, stat);
323 GdipDeletePathIter(iter);
324
325 /* on empty path */
326 GdipCreatePathIter(&iter, path);
327 isvalid = FALSE;
328 stat = GdipPathIterIsValid(iter, &isvalid);
329 expect(Ok, stat);
330 expect(TRUE, isvalid);
331 GdipDeletePathIter(iter);
332
333 /* no markers */
334 stat = GdipAddPathLine(path, 50.0, 50.0, 110.0, 40.0);
335 expect(Ok, stat);
336 stat = GdipCreatePathIter(&iter, path);
337 expect(Ok, stat);
338 stat = GdipPathIterNextMarker(iter, &result, &start, &end);
339 expect(Ok, stat);
340 isvalid = FALSE;
341 stat = GdipPathIterIsValid(iter, &isvalid);
342 expect(Ok, stat);
343 expect(TRUE, isvalid);
344 GdipDeletePathIter(iter);
345
346 GdipDeletePath(path);
347 }
348
349 static void test_nextsubpathpath(void)
350 {
351 GpPath *path, *retpath;
352 GpPathIterator *iter;
353 GpStatus stat;
354 BOOL closed;
355 INT count, result;
356
357 GdipCreatePath(FillModeAlternate, &path);
358
359 /* NULL args */
360 GdipCreatePath(FillModeAlternate, &retpath);
361 GdipCreatePathIter(&iter, path);
362 stat = GdipPathIterNextSubpathPath(NULL, NULL, NULL, NULL);
363 expect(InvalidParameter, stat);
364 stat = GdipPathIterNextSubpathPath(iter, NULL, NULL, NULL);
365 expect(InvalidParameter, stat);
366 stat = GdipPathIterNextSubpathPath(NULL, &result, NULL, NULL);
367 expect(InvalidParameter, stat);
368 stat = GdipPathIterNextSubpathPath(iter, &result, NULL, &closed);
369 expect(Ok, stat);
370 stat = GdipPathIterNextSubpathPath(iter, NULL, NULL, &closed);
371 expect(InvalidParameter, stat);
372 stat = GdipPathIterNextSubpathPath(iter, NULL, retpath, NULL);
373 expect(InvalidParameter, stat);
374 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, NULL);
375 expect(InvalidParameter, stat);
376 GdipDeletePathIter(iter);
377 GdipDeletePath(retpath);
378
379 /* empty path */
380 GdipCreatePath(FillModeAlternate, &retpath);
381 GdipCreatePathIter(&iter, path);
382 result = -2;
383 closed = TRUE;
384 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
385 expect(Ok, stat);
386 expect(0, result);
387 expect(TRUE, closed);
388 count = -1;
389 GdipGetPointCount(retpath, &count);
390 expect(0, count);
391 GdipDeletePathIter(iter);
392 GdipDeletePath(retpath);
393
394 /* open figure */
395 GdipAddPathLine(path, 5.0, 5.0, 100.0, 50.0);
396
397 GdipCreatePath(FillModeAlternate, &retpath);
398 GdipCreatePathIter(&iter, path);
399 result = -2;
400 closed = TRUE;
401 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
402 expect(Ok, stat);
403 expect(2, result);
404 expect(FALSE, closed);
405 count = -1;
406 GdipGetPointCount(retpath, &count);
407 expect(2, count);
408 /* subsequent call */
409 result = -2;
410 closed = TRUE;
411 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
412 expect(Ok, stat);
413 expect(0, result);
414 expect(TRUE, closed);
415 count = -1;
416 GdipGetPointCount(retpath, &count);
417 expect(2, count);
418 GdipDeletePathIter(iter);
419
420 /* closed figure, check does it extend retpath or reset it */
421 GdipAddPathLine(retpath, 50.0, 55.0, 200.0, 150.0);
422
423 GdipClosePathFigure(path);
424 GdipAddPathLine(path, 50.0, 55.0, 200.0, 150.0);
425 GdipClosePathFigure(path);
426
427 GdipCreatePathIter(&iter, path);
428 result = -2;
429 closed = FALSE;
430 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
431 expect(Ok, stat);
432 expect(2, result);
433 expect(TRUE, closed);
434 count = -1;
435 GdipGetPointCount(retpath, &count);
436 expect(2, count);
437 /* subsequent call */
438 result = -2;
439 closed = FALSE;
440 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
441 expect(Ok, stat);
442 expect(2, result);
443 expect(TRUE, closed);
444 count = -1;
445 GdipGetPointCount(retpath, &count);
446 expect(2, count);
447 result = -2;
448 closed = FALSE;
449 stat = GdipPathIterNextSubpathPath(iter, &result, retpath, &closed);
450 expect(Ok, stat);
451 expect(0, result);
452 expect(TRUE, closed);
453 count = -1;
454 GdipGetPointCount(retpath, &count);
455 expect(2, count);
456 GdipDeletePathIter(iter);
457
458 GdipDeletePath(retpath);
459 GdipDeletePath(path);
460 }
461
462 static void test_nextsubpath(void)
463 {
464 GpPath *path;
465 GpPathIterator *iter;
466 GpStatus stat;
467 INT start, end, result;
468 BOOL closed;
469
470 /* empty path */
471 GdipCreatePath(FillModeAlternate, &path);
472 GdipCreatePathIter(&iter, path);
473
474 result = -2;
475 closed = TRUE;
476 stat = GdipPathIterNextSubpath(iter, &result, &start, &end, &closed);
477 expect(Ok, stat);
478 expect(0, result);
479 expect(TRUE, closed);
480
481 GdipDeletePathIter(iter);
482 GdipDeletePath(path);
483 }
484
485 static void test_nextpathtype(void)
486 {
487 GpPath *path;
488 GpPathIterator *iter;
489 GpStatus stat;
490 INT start, end, result;
491 BYTE type;
492
493 GdipCreatePath(FillModeAlternate, &path);
494 GdipCreatePathIter(&iter, path);
495
496 /* NULL arguments */
497 stat = GdipPathIterNextPathType(NULL, NULL, NULL, NULL, NULL);
498 expect(InvalidParameter, stat);
499 stat = GdipPathIterNextPathType(iter, NULL, NULL, NULL, NULL);
500 expect(InvalidParameter, stat);
501 stat = GdipPathIterNextPathType(iter, &result, NULL, NULL, NULL);
502 expect(InvalidParameter, stat);
503 stat = GdipPathIterNextPathType(iter, NULL, &type, NULL, NULL);
504 expect(InvalidParameter, stat);
505 stat = GdipPathIterNextPathType(iter, NULL, NULL, &start, &end);
506 expect(InvalidParameter, stat);
507 stat = GdipPathIterNextPathType(iter, NULL, &type, &start, &end);
508 expect(InvalidParameter, stat);
509 stat = GdipPathIterNextPathType(iter, &result, &type, NULL, NULL);
510 expect(InvalidParameter, stat);
511
512 /* empty path */
513 start = end = result = (INT)0xdeadbeef;
514 stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
515 todo_wine expect(Ok, stat);
516 expect((INT)0xdeadbeef, start);
517 expect((INT)0xdeadbeef, end);
518 todo_wine expect(0, result);
519 GdipDeletePathIter(iter);
520
521 /* single figure */
522 GdipAddPathLine(path, 0.0, 0.0, 10.0, 30.0);
523 GdipCreatePathIter(&iter, path);
524 start = end = result = (INT)0xdeadbeef;
525 type = 255; /* out of range */
526 stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
527 todo_wine expect(Ok, stat);
528 expect((INT)0xdeadbeef, start);
529 expect((INT)0xdeadbeef, end);
530 expect(255, type);
531 todo_wine expect(0, result);
532 GdipDeletePathIter(iter);
533
534 stat = GdipAddPathEllipse(path, 0.0, 0.0, 35.0, 70.0);
535 expect(Ok, stat);
536 GdipCreatePathIter(&iter, path);
537 start = end = result = (INT)0xdeadbeef;
538 type = 255; /* out of range */
539 stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
540 todo_wine expect(Ok, stat);
541 expect((INT)0xdeadbeef, start);
542 expect((INT)0xdeadbeef, end);
543 expect(255, type);
544 todo_wine expect(0, result);
545 GdipDeletePathIter(iter);
546
547 /* closed */
548 GdipClosePathFigure(path);
549 GdipCreatePathIter(&iter, path);
550 start = end = result = (INT)0xdeadbeef;
551 type = 255; /* out of range */
552 stat = GdipPathIterNextPathType(iter, &result, &type, &start, &end);
553 todo_wine expect(Ok, stat);
554 expect((INT)0xdeadbeef, start);
555 expect((INT)0xdeadbeef, end);
556 expect(255, type);
557 todo_wine expect(0, result);
558 GdipDeletePathIter(iter);
559
560 GdipDeletePath(path);
561 }
562
563 START_TEST(pathiterator)
564 {
565 struct GdiplusStartupInput gdiplusStartupInput;
566 ULONG_PTR gdiplusToken;
567 HMODULE hmsvcrt;
568 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
569
570 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
571 hmsvcrt = LoadLibraryA("msvcrt");
572 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
573 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
574
575 gdiplusStartupInput.GdiplusVersion = 1;
576 gdiplusStartupInput.DebugEventCallback = NULL;
577 gdiplusStartupInput.SuppressBackgroundThread = 0;
578 gdiplusStartupInput.SuppressExternalCodecs = 0;
579
580 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
581
582 test_constructor_destructor();
583 test_hascurve();
584 test_nextmarker();
585 test_nextmarkerpath();
586 test_getsubpathcount();
587 test_isvalid();
588 test_nextsubpathpath();
589 test_nextsubpath();
590 test_nextpathtype();
591
592 GdiplusShutdown(gdiplusToken);
593 }