setupapi: Fix resolving target path when given a section. Default to the system direc...
[wine] / dlls / gdiplus / tests / graphics.c
1 /*
2  * Unit test suite for graphics objects
3  *
4  * Copyright (C) 2007 Google (Evan Stade)
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 expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
27 #define TABLE_LEN (23)
28
29 static void test_constructor_destructor(void)
30 {
31     GpStatus stat;
32     GpGraphics *graphics = NULL;
33     HDC hdc = GetDC(0);
34
35     stat = GdipCreateFromHDC(NULL, &graphics);
36     expect(OutOfMemory, stat);
37     stat = GdipDeleteGraphics(graphics);
38     expect(InvalidParameter, stat);
39
40     stat = GdipCreateFromHDC(hdc, &graphics);
41     expect(Ok, stat);
42     stat = GdipDeleteGraphics(graphics);
43     expect(Ok, stat);
44
45     stat = GdipCreateFromHWND(NULL, &graphics);
46     expect(Ok, stat);
47     stat = GdipDeleteGraphics(graphics);
48     expect(Ok, stat);
49
50     stat = GdipCreateFromHWNDICM(NULL, &graphics);
51     expect(Ok, stat);
52     stat = GdipDeleteGraphics(graphics);
53     expect(Ok, stat);
54
55     stat = GdipDeleteGraphics(NULL);
56     expect(InvalidParameter, stat);
57     ReleaseDC(0, hdc);
58 }
59
60 typedef struct node{
61     GraphicsState data;
62     struct node * next;
63 } node;
64
65 /* Linked list prepend function. */
66 static void log_state(GraphicsState data, node ** log)
67 {
68     node * new_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(node));
69
70     new_entry->data = data;
71     new_entry->next = *log;
72     *log = new_entry;
73 }
74
75 /* Checks if there are duplicates in the list, and frees it. */
76 static void check_no_duplicates(node * log)
77 {
78     INT dups = 0;
79     node * temp = NULL;
80     node * temp2 = NULL;
81     node * orig = log;
82
83     if(!log)
84         goto end;
85
86     do{
87         temp = log;
88         while((temp = temp->next)){
89             if(log->data == temp->data){
90                 dups++;
91                 break;
92             }
93             if(dups > 0)
94                 break;
95         }
96     }while((log = log->next));
97
98     temp = orig;
99     do{
100         temp2 = temp->next;
101         HeapFree(GetProcessHeap(), 0, temp);
102         temp = temp2;
103     }while(temp);
104
105 end:
106     expect(0, dups);
107 }
108
109 static void test_save_restore(void)
110 {
111     GpStatus stat;
112     GraphicsState state_a, state_b, state_c;
113     InterpolationMode mode;
114     GpGraphics *graphics1, *graphics2;
115     node * state_log = NULL;
116     HDC hdc = GetDC(0);
117     state_a = state_b = state_c = 0xdeadbeef;
118
119     /* Invalid saving. */
120     GdipCreateFromHDC(hdc, &graphics1);
121     stat = GdipSaveGraphics(graphics1, NULL);
122     expect(InvalidParameter, stat);
123     stat = GdipSaveGraphics(NULL, &state_a);
124     expect(InvalidParameter, stat);
125     GdipDeleteGraphics(graphics1);
126
127     log_state(state_a, &state_log);
128
129     /* Basic save/restore. */
130     GdipCreateFromHDC(hdc, &graphics1);
131     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
132     stat = GdipSaveGraphics(graphics1, &state_a);
133     expect(Ok, stat);
134     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
135     stat = GdipRestoreGraphics(graphics1, state_a);
136     expect(Ok, stat);
137     GdipGetInterpolationMode(graphics1, &mode);
138     todo_wine
139         expect(InterpolationModeBilinear, mode);
140     GdipDeleteGraphics(graphics1);
141
142     log_state(state_a, &state_log);
143
144     /* Restoring garbage doesn't affect saves. */
145     GdipCreateFromHDC(hdc, &graphics1);
146     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
147     GdipSaveGraphics(graphics1, &state_a);
148     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
149     GdipSaveGraphics(graphics1, &state_b);
150     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
151     stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
152     expect(Ok, stat);
153     GdipRestoreGraphics(graphics1, state_b);
154     GdipGetInterpolationMode(graphics1, &mode);
155     todo_wine
156         expect(InterpolationModeBicubic, mode);
157     GdipRestoreGraphics(graphics1, state_a);
158     GdipGetInterpolationMode(graphics1, &mode);
159     todo_wine
160         expect(InterpolationModeBilinear, mode);
161     GdipDeleteGraphics(graphics1);
162
163     log_state(state_a, &state_log);
164     log_state(state_b, &state_log);
165
166     /* Restoring older state invalidates newer saves (but not older saves). */
167     GdipCreateFromHDC(hdc, &graphics1);
168     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
169     GdipSaveGraphics(graphics1, &state_a);
170     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
171     GdipSaveGraphics(graphics1, &state_b);
172     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
173     GdipSaveGraphics(graphics1, &state_c);
174     GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
175     GdipRestoreGraphics(graphics1, state_b);
176     GdipGetInterpolationMode(graphics1, &mode);
177     todo_wine
178         expect(InterpolationModeBicubic, mode);
179     GdipRestoreGraphics(graphics1, state_c);
180     GdipGetInterpolationMode(graphics1, &mode);
181     todo_wine
182         expect(InterpolationModeBicubic, mode);
183     GdipRestoreGraphics(graphics1, state_a);
184     GdipGetInterpolationMode(graphics1, &mode);
185     todo_wine
186         expect(InterpolationModeBilinear, mode);
187     GdipDeleteGraphics(graphics1);
188
189     log_state(state_a, &state_log);
190     log_state(state_b, &state_log);
191     log_state(state_c, &state_log);
192
193     /* Restoring older save from one graphics object does not invalidate
194      * newer save from other graphics object. */
195     GdipCreateFromHDC(hdc, &graphics1);
196     GdipCreateFromHDC(hdc, &graphics2);
197     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
198     GdipSaveGraphics(graphics1, &state_a);
199     GdipSetInterpolationMode(graphics2, InterpolationModeBicubic);
200     GdipSaveGraphics(graphics2, &state_b);
201     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
202     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
203     GdipRestoreGraphics(graphics1, state_a);
204     GdipGetInterpolationMode(graphics1, &mode);
205     todo_wine
206         expect(InterpolationModeBilinear, mode);
207     GdipRestoreGraphics(graphics2, state_b);
208     GdipGetInterpolationMode(graphics2, &mode);
209     todo_wine
210         expect(InterpolationModeBicubic, mode);
211     GdipDeleteGraphics(graphics1);
212     GdipDeleteGraphics(graphics2);
213
214     /* You can't restore a state to a graphics object that didn't save it. */
215     GdipCreateFromHDC(hdc, &graphics1);
216     GdipCreateFromHDC(hdc, &graphics2);
217     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
218     GdipSaveGraphics(graphics1, &state_a);
219     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
220     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
221     GdipRestoreGraphics(graphics2, state_a);
222     GdipGetInterpolationMode(graphics2, &mode);
223     expect(InterpolationModeNearestNeighbor, mode);
224     GdipDeleteGraphics(graphics1);
225     GdipDeleteGraphics(graphics2);
226
227     log_state(state_a, &state_log);
228
229     /* The same state value should never be returned twice. */
230     todo_wine
231         check_no_duplicates(state_log);
232
233     ReleaseDC(0, hdc);
234 }
235
236 static void test_GdipDrawArc(void)
237 {
238     GpStatus status;
239     GpGraphics *graphics = NULL;
240     GpPen *pen = NULL;
241     HDC hdc = GetDC(0);
242
243     /* make a graphics object and pen object */
244     status = GdipCreateFromHDC(hdc, &graphics);
245     expect(Ok, status);
246     ok(hdc != NULL, "Expected HDC to be initialized\n");
247
248     status = GdipCreateFromHDC(hdc, &graphics);
249     expect(Ok, status);
250     ok(graphics != NULL, "Expected graphics to be initialized\n");
251
252     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
253     expect(Ok, status);
254     ok(pen != NULL, "Expected pen to be initialized\n");
255
256     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
257     status = GdipDrawArc(NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
258     expect(InvalidParameter, status);
259
260     status = GdipDrawArc(graphics, NULL, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
261     expect(InvalidParameter, status);
262
263     status = GdipDrawArc(NULL, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
264     expect(InvalidParameter, status);
265
266     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
267     expect(InvalidParameter, status);
268
269     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
270     expect(InvalidParameter, status);
271
272     /* successful case */
273     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
274     expect(Ok, status);
275
276     GdipDeletePen(pen);
277     GdipDeleteGraphics(graphics);
278
279     ReleaseDC(0, hdc);
280 }
281
282 static void test_GdipDrawArcI(void)
283 {
284     GpStatus status;
285     GpGraphics *graphics = NULL;
286     GpPen *pen = NULL;
287     HDC hdc = GetDC(0);
288
289     /* make a graphics object and pen object */
290     status = GdipCreateFromHDC(hdc, &graphics);
291     expect(Ok, status);
292     ok(hdc != NULL, "Expected HDC to be initialized\n");
293
294     status = GdipCreateFromHDC(hdc, &graphics);
295     expect(Ok, status);
296     ok(graphics != NULL, "Expected graphics to be initialized\n");
297
298     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
299     expect(Ok, status);
300     ok(pen != NULL, "Expected pen to be initialized\n");
301
302     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
303     status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
304     expect(InvalidParameter, status);
305
306     status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
307     expect(InvalidParameter, status);
308
309     status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
310     expect(InvalidParameter, status);
311
312     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
313     expect(InvalidParameter, status);
314
315     status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
316     expect(InvalidParameter, status);
317
318     /* successful case */
319     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
320     expect(Ok, status);
321
322     GdipDeletePen(pen);
323     GdipDeleteGraphics(graphics);
324
325     ReleaseDC(0, hdc);
326 }
327
328 static void test_GdipDrawBezierI(void)
329 {
330     GpStatus status;
331     GpGraphics *graphics = NULL;
332     GpPen *pen = NULL;
333     HDC hdc = GetDC(0);
334
335     /* make a graphics object and pen object */
336     status = GdipCreateFromHDC(hdc, &graphics);
337     expect(Ok, status);
338     ok(hdc != NULL, "Expected HDC to be initialized\n");
339
340     status = GdipCreateFromHDC(hdc, &graphics);
341     expect(Ok, status);
342     ok(graphics != NULL, "Expected graphics to be initialized\n");
343
344     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
345     expect(Ok, status);
346     ok(pen != NULL, "Expected pen to be initialized\n");
347
348     /* InvalidParameter cases: null graphics, null pen */
349     status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
350     expect(InvalidParameter, status);
351
352     status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
353     expect(InvalidParameter, status);
354
355     status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
356     expect(InvalidParameter, status);
357
358     /* successful case */
359     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
360     expect(Ok, status);
361
362     GdipDeletePen(pen);
363     GdipDeleteGraphics(graphics);
364
365     ReleaseDC(0, hdc);
366 }
367
368 static void test_GdipDrawLineI(void)
369 {
370     GpStatus status;
371     GpGraphics *graphics = NULL;
372     GpPen *pen = NULL;
373     HDC hdc = GetDC(0);
374
375     /* make a graphics object and pen object */
376     status = GdipCreateFromHDC(hdc, &graphics);
377     expect(Ok, status);
378     ok(hdc != NULL, "Expected HDC to be initialized\n");
379
380     status = GdipCreateFromHDC(hdc, &graphics);
381     expect(Ok, status);
382     ok(graphics != NULL, "Expected graphics to be initialized\n");
383
384     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
385     expect(Ok, status);
386     ok(pen != NULL, "Expected pen to be initialized\n");
387
388     /* InvalidParameter cases: null graphics, null pen */
389     status = GdipDrawLineI(NULL, NULL, 0, 0, 0, 0);
390     expect(InvalidParameter, status);
391
392     status = GdipDrawLineI(graphics, NULL, 0, 0, 0, 0);
393     expect(InvalidParameter, status);
394
395     status = GdipDrawLineI(NULL, pen, 0, 0, 0, 0);
396     expect(InvalidParameter, status);
397
398     /* successful case */
399     status = GdipDrawLineI(graphics, pen, 0, 0, 0, 0);
400     expect(Ok, status);
401
402     GdipDeletePen(pen);
403     GdipDeleteGraphics(graphics);
404
405     ReleaseDC(0, hdc);
406 }
407
408 static void test_GdipDrawLinesI(void)
409 {
410     GpStatus status;
411     GpGraphics *graphics = NULL;
412     GpPen *pen = NULL;
413     GpPoint *ptf = NULL;
414     HDC hdc = GetDC(0);
415
416     /* make a graphics object and pen object */
417     status = GdipCreateFromHDC(hdc, &graphics);
418     expect(Ok, status);
419     ok(hdc != NULL, "Expected HDC to be initialized\n");
420
421     status = GdipCreateFromHDC(hdc, &graphics);
422     expect(Ok, status);
423     ok(graphics != NULL, "Expected graphics to be initialized\n");
424
425     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
426     expect(Ok, status);
427     ok(pen != NULL, "Expected pen to be initialized\n");
428
429     /* make some arbitrary valid points*/
430     ptf = GdipAlloc(2 * sizeof(GpPointF));
431
432     ptf[0].X = 1;
433     ptf[0].Y = 1;
434
435     ptf[1].X = 2;
436     ptf[1].Y = 2;
437
438     /* InvalidParameter cases: null graphics, null pen, null points, count < 2*/
439     status = GdipDrawLinesI(NULL, NULL, NULL, 0);
440     expect(InvalidParameter, status);
441
442     status = GdipDrawLinesI(graphics, pen, ptf, 0);
443     expect(InvalidParameter, status);
444
445     status = GdipDrawLinesI(graphics, NULL, ptf, 2);
446     expect(InvalidParameter, status);
447
448     status = GdipDrawLinesI(NULL, pen, ptf, 2);
449     expect(InvalidParameter, status);
450
451     /* successful case */
452     status = GdipDrawLinesI(graphics, pen, ptf, 2);
453     expect(Ok, status);
454
455     GdipFree(ptf);
456     GdipDeletePen(pen);
457     GdipDeleteGraphics(graphics);
458
459     ReleaseDC(0, hdc);
460 }
461
462 static void test_Get_Release_DC(void)
463 {
464     GpStatus status;
465     GpGraphics *graphics = NULL;
466     GpPen *pen;
467     GpSolidFill *brush;
468     GpPath *path;
469     HDC hdc = GetDC(0);
470     HDC retdc;
471     REAL r;
472     CompositingQuality quality;
473     CompositingMode compmode;
474     InterpolationMode intmode;
475     GpMatrix *m;
476     GpRegion *region;
477     GpUnit unit;
478     PixelOffsetMode offsetmode;
479     SmoothingMode smoothmode;
480     TextRenderingHint texthint;
481     GpPointF ptf[5];
482     GpPoint  pt[5];
483     GpRectF  rectf[2];
484     GpRect   rect[2];
485     GpRegion *clip;
486     INT i;
487     BOOL res;
488     ARGB color = 0x00000000;
489
490     pt[0].X = 10;
491     pt[0].Y = 10;
492     pt[1].X = 20;
493     pt[1].Y = 15;
494     pt[2].X = 40;
495     pt[2].Y = 80;
496     pt[3].X = -20;
497     pt[3].Y = 20;
498     pt[4].X = 50;
499     pt[4].Y = 110;
500
501     for(i = 0; i < 5;i++){
502         ptf[i].X = (REAL)pt[i].X;
503         ptf[i].Y = (REAL)pt[i].Y;
504     }
505
506     rect[0].X = 0;
507     rect[0].Y = 0;
508     rect[0].Width  = 50;
509     rect[0].Height = 70;
510     rect[1].X = 0;
511     rect[1].Y = 0;
512     rect[1].Width  = 10;
513     rect[1].Height = 20;
514
515     for(i = 0; i < 2;i++){
516         rectf[i].X = (REAL)rect[i].X;
517         rectf[i].Y = (REAL)rect[i].Y;
518         rectf[i].Height = (REAL)rect[i].Height;
519         rectf[i].Width  = (REAL)rect[i].Width;
520     }
521
522     GdipCreateMatrix(&m);
523     GdipCreateRegion(&region);
524     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
525     GdipCreatePath(FillModeAlternate, &path);
526     GdipCreateRegion(&clip);
527
528     status = GdipCreateFromHDC(hdc, &graphics);
529     expect(Ok, status);
530     ok(graphics != NULL, "Expected graphics to be initialized\n");
531     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
532     expect(Ok, status);
533
534     /* NULL arguments */
535     status = GdipGetDC(NULL, NULL);
536     expect(InvalidParameter, status);
537     status = GdipGetDC(graphics, NULL);
538     expect(InvalidParameter, status);
539     status = GdipGetDC(NULL, &retdc);
540     expect(InvalidParameter, status);
541
542     status = GdipReleaseDC(NULL, NULL);
543     expect(InvalidParameter, status);
544     status = GdipReleaseDC(graphics, NULL);
545     expect(InvalidParameter, status);
546     status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
547     expect(InvalidParameter, status);
548
549     /* Release without Get */
550     status = GdipReleaseDC(graphics, hdc);
551     expect(InvalidParameter, status);
552
553     retdc = NULL;
554     status = GdipGetDC(graphics, &retdc);
555     expect(Ok, status);
556     ok(retdc == hdc, "Invalid HDC returned\n");
557     /* call it once more */
558     status = GdipGetDC(graphics, &retdc);
559     expect(ObjectBusy, status);
560
561     /* try all Graphics calls here */
562     status = Ok;
563     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
564     expect(ObjectBusy, status); status = Ok;
565     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
566     expect(ObjectBusy, status); status = Ok;
567     status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
568     expect(ObjectBusy, status); status = Ok;
569     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
570     expect(ObjectBusy, status); status = Ok;
571     status = GdipDrawBeziers(graphics, pen, ptf, 5);
572     expect(ObjectBusy, status); status = Ok;
573     status = GdipDrawBeziersI(graphics, pen, pt, 5);
574     expect(ObjectBusy, status); status = Ok;
575     status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
576     expect(ObjectBusy, status); status = Ok;
577     status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
578     expect(ObjectBusy, status); status = Ok;
579     status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
580     expect(ObjectBusy, status); status = Ok;
581     status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
582     expect(ObjectBusy, status); status = Ok;
583     status = GdipDrawCurve(graphics, pen, ptf, 5);
584     expect(ObjectBusy, status); status = Ok;
585     status = GdipDrawCurveI(graphics, pen, pt, 5);
586     expect(ObjectBusy, status); status = Ok;
587     status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
588     expect(ObjectBusy, status); status = Ok;
589     status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
590     expect(ObjectBusy, status); status = Ok;
591     status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
592     expect(ObjectBusy, status); status = Ok;
593     status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
594     expect(ObjectBusy, status); status = Ok;
595     /* GdipDrawImage/GdipDrawImageI */
596     /* GdipDrawImagePointsRect/GdipDrawImagePointsRectI */
597     /* GdipDrawImageRectRect/GdipDrawImageRectRectI */
598     /* GdipDrawImageRect/GdipDrawImageRectI */
599     status = GdipDrawLine(graphics, pen, 0.0, 0.0, 100.0, 200.0);
600     expect(ObjectBusy, status); status = Ok;
601     status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
602     expect(ObjectBusy, status); status = Ok;
603     status = GdipDrawLines(graphics, pen, ptf, 5);
604     expect(ObjectBusy, status); status = Ok;
605     status = GdipDrawLinesI(graphics, pen, pt, 5);
606     expect(ObjectBusy, status); status = Ok;
607     status = GdipDrawPath(graphics, pen, path);
608     expect(ObjectBusy, status); status = Ok;
609     status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
610     expect(ObjectBusy, status); status = Ok;
611     status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
612     expect(ObjectBusy, status); status = Ok;
613     status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
614     expect(ObjectBusy, status); status = Ok;
615     status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
616     expect(ObjectBusy, status); status = Ok;
617     status = GdipDrawRectangles(graphics, pen, rectf, 2);
618     expect(ObjectBusy, status); status = Ok;
619     status = GdipDrawRectanglesI(graphics, pen, rect, 2);
620     expect(ObjectBusy, status); status = Ok;
621     /* GdipDrawString */
622     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
623     expect(ObjectBusy, status); status = Ok;
624     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
625     expect(ObjectBusy, status); status = Ok;
626     status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
627     expect(ObjectBusy, status); status = Ok;
628     status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
629     expect(ObjectBusy, status); status = Ok;
630     status = GdipFillPath(graphics, (GpBrush*)brush, path);
631     expect(ObjectBusy, status); status = Ok;
632     status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
633     expect(ObjectBusy, status); status = Ok;
634     status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
635     expect(ObjectBusy, status); status = Ok;
636     status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
637     expect(ObjectBusy, status); status = Ok;
638     status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
639     expect(ObjectBusy, status); status = Ok;
640     status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
641     expect(ObjectBusy, status); status = Ok;
642     status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
643     expect(ObjectBusy, status); status = Ok;
644     status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
645     expect(ObjectBusy, status); status = Ok;
646     status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
647     expect(ObjectBusy, status); status = Ok;
648     status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
649     expect(ObjectBusy, status); status = Ok;
650     status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
651     expect(ObjectBusy, status); status = Ok;
652     status = GdipFillRegion(graphics, (GpBrush*)brush, region);
653     expect(ObjectBusy, status); status = Ok;
654     status = GdipFlush(graphics, FlushIntentionFlush);
655     expect(ObjectBusy, status); status = Ok;
656     status = GdipGetCompositingMode(graphics, &compmode);
657     expect(ObjectBusy, status); status = Ok;
658     status = GdipGetCompositingQuality(graphics, &quality);
659     expect(ObjectBusy, status); status = Ok;
660     status = GdipGetInterpolationMode(graphics, &intmode);
661     expect(ObjectBusy, status); status = Ok;
662     status = GdipGetNearestColor(graphics, &color);
663     expect(ObjectBusy, status); status = Ok;
664     status = GdipGetPageScale(graphics, &r);
665     expect(ObjectBusy, status); status = Ok;
666     status = GdipGetPageUnit(graphics, &unit);
667     expect(ObjectBusy, status); status = Ok;
668     status = GdipGetPixelOffsetMode(graphics, &offsetmode);
669     expect(ObjectBusy, status); status = Ok;
670     status = GdipGetSmoothingMode(graphics, &smoothmode);
671     expect(ObjectBusy, status); status = Ok;
672     status = GdipGetTextRenderingHint(graphics, &texthint);
673     expect(ObjectBusy, status); status = Ok;
674     status = GdipGetWorldTransform(graphics, m);
675     expect(ObjectBusy, status); status = Ok;
676     status = GdipGraphicsClear(graphics, 0xdeadbeef);
677     expect(ObjectBusy, status); status = Ok;
678     status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
679     expect(ObjectBusy, status); status = Ok;
680     status = GdipIsVisiblePointI(graphics, 0, 0, &res);
681     expect(ObjectBusy, status); status = Ok;
682     /* GdipMeasureCharacterRanges */
683     /* GdipMeasureString */
684     status = GdipResetClip(graphics);
685     expect(ObjectBusy, status); status = Ok;
686     status = GdipResetWorldTransform(graphics);
687     expect(ObjectBusy, status); status = Ok;
688     /* GdipRestoreGraphics */
689     status = GdipRotateWorldTransform(graphics, 15.0, MatrixOrderPrepend);
690     expect(ObjectBusy, status); status = Ok;
691     /*  GdipSaveGraphics */
692     status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
693     expect(ObjectBusy, status); status = Ok;
694     status = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
695     expect(ObjectBusy, status); status = Ok;
696     status = GdipSetCompositingQuality(graphics, CompositingQualityDefault);
697     expect(ObjectBusy, status); status = Ok;
698     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
699     expect(ObjectBusy, status); status = Ok;
700     status = GdipSetPageScale(graphics, 1.0);
701     expect(ObjectBusy, status); status = Ok;
702     status = GdipSetPageUnit(graphics, UnitWorld);
703     expect(ObjectBusy, status); status = Ok;
704     status = GdipSetPixelOffsetMode(graphics, PixelOffsetModeDefault);
705     expect(ObjectBusy, status); status = Ok;
706     status = GdipSetSmoothingMode(graphics, SmoothingModeDefault);
707     expect(ObjectBusy, status); status = Ok;
708     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
709     expect(ObjectBusy, status); status = Ok;
710     status = GdipSetWorldTransform(graphics, m);
711     expect(ObjectBusy, status); status = Ok;
712     status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
713     expect(ObjectBusy, status); status = Ok;
714     status = GdipSetClipPath(graphics, path, CombineModeReplace);
715     expect(ObjectBusy, status); status = Ok;
716     status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
717     expect(ObjectBusy, status); status = Ok;
718     status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
719     expect(ObjectBusy, status); status = Ok;
720     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
721     expect(ObjectBusy, status);
722     status = GdipDrawPolygon(graphics, pen, ptf, 5);
723     expect(ObjectBusy, status); status = Ok;
724     status = GdipDrawPolygonI(graphics, pen, pt, 5);
725     expect(ObjectBusy, status); status = Ok;
726     status = GdipGetDpiX(graphics, &r);
727     expect(ObjectBusy, status); status = Ok;
728     status = GdipGetDpiY(graphics, &r);
729     expect(ObjectBusy, status); status = Ok;
730     status = GdipMultiplyWorldTransform(graphics, m, MatrixOrderPrepend);
731     status = GdipGetClip(graphics, region);
732     expect(ObjectBusy, status); status = Ok;
733     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 5);
734     expect(ObjectBusy, status); status = Ok;
735     /* try to delete before release */
736     status = GdipDeleteGraphics(graphics);
737     expect(ObjectBusy, status);
738
739     status = GdipReleaseDC(graphics, retdc);
740     expect(Ok, status);
741
742     GdipDeletePen(pen);
743     GdipDeleteGraphics(graphics);
744
745     GdipDeletePath(path);
746     GdipDeleteBrush((GpBrush*)brush);
747     GdipDeleteRegion(region);
748     GdipDeleteMatrix(m);
749
750     ReleaseDC(0, hdc);
751 }
752
753 static void test_transformpoints(void)
754 {
755     GpStatus status;
756     GpGraphics *graphics = NULL;
757     HDC hdc = GetDC(0);
758     GpPointF ptf[5];
759     INT i;
760
761     status = GdipCreateFromHDC(hdc, &graphics);
762     expect(Ok, status);
763
764     for(i = 0; i < 5; i++){
765         ptf[i].X = 200.0 + i * 50.0 * (i % 2);
766         ptf[i].Y = 200.0 + i * 50.0 * !(i % 2);
767     }
768
769     /* NULL arguments */
770     status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
771     expect(InvalidParameter, status);
772     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
773     expect(InvalidParameter, status);
774     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 0);
775     expect(InvalidParameter, status);
776     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1);
777     expect(InvalidParameter, status);
778
779     GdipDeleteGraphics(graphics);
780     ReleaseDC(0, hdc);
781 }
782
783 static void test_get_set_clip(void)
784 {
785     GpStatus status;
786     GpGraphics *graphics = NULL;
787     HDC hdc = GetDC(0);
788     GpRegion *clip;
789     GpRectF rect;
790     BOOL res;
791
792     status = GdipCreateFromHDC(hdc, &graphics);
793     expect(Ok, status);
794
795     rect.X = rect.Y = 0.0;
796     rect.Height = rect.Width = 100.0;
797
798     status = GdipCreateRegionRect(&rect, &clip);
799
800     /* NULL arguments */
801     status = GdipGetClip(NULL, NULL);
802     expect(InvalidParameter, status);
803     status = GdipGetClip(graphics, NULL);
804     expect(InvalidParameter, status);
805     status = GdipGetClip(NULL, clip);
806     expect(InvalidParameter, status);
807
808     status = GdipSetClipRegion(NULL, NULL, CombineModeReplace);
809     expect(InvalidParameter, status);
810     status = GdipSetClipRegion(graphics, NULL, CombineModeReplace);
811     expect(InvalidParameter, status);
812
813     status = GdipSetClipPath(NULL, NULL, CombineModeReplace);
814     expect(InvalidParameter, status);
815     status = GdipSetClipPath(graphics, NULL, CombineModeReplace);
816     expect(InvalidParameter, status);
817
818     res = FALSE;
819     status = GdipGetClip(graphics, clip);
820     expect(Ok, status);
821     status = GdipIsInfiniteRegion(clip, graphics, &res);
822     expect(Ok, status);
823     expect(TRUE, res);
824
825     /* remains infinite after reset */
826     res = FALSE;
827     status = GdipResetClip(graphics);
828     expect(Ok, status);
829     status = GdipGetClip(graphics, clip);
830     expect(Ok, status);
831     status = GdipIsInfiniteRegion(clip, graphics, &res);
832     expect(Ok, status);
833     expect(TRUE, res);
834
835     /* set to empty and then reset to infinite */
836     status = GdipSetEmpty(clip);
837     expect(Ok, status);
838     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
839     expect(Ok, status);
840
841     status = GdipGetClip(graphics, clip);
842     expect(Ok, status);
843     res = FALSE;
844     status = GdipIsEmptyRegion(clip, graphics, &res);
845     expect(Ok, status);
846     expect(TRUE, res);
847     status = GdipResetClip(graphics);
848     expect(Ok, status);
849     status = GdipGetClip(graphics, clip);
850     expect(Ok, status);
851     res = FALSE;
852     status = GdipIsInfiniteRegion(clip, graphics, &res);
853     expect(Ok, status);
854     expect(TRUE, res);
855
856     GdipDeleteRegion(clip);
857
858     GdipDeleteGraphics(graphics);
859     ReleaseDC(0, hdc);
860 }
861
862 static void test_isempty(void)
863 {
864     GpStatus status;
865     GpGraphics *graphics = NULL;
866     HDC hdc = GetDC(0);
867     GpRegion *clip;
868     BOOL res;
869
870     status = GdipCreateFromHDC(hdc, &graphics);
871     expect(Ok, status);
872
873     status = GdipCreateRegion(&clip);
874     expect(Ok, status);
875
876     /* NULL */
877     status = GdipIsClipEmpty(NULL, NULL);
878     expect(InvalidParameter, status);
879     status = GdipIsClipEmpty(graphics, NULL);
880     expect(InvalidParameter, status);
881     status = GdipIsClipEmpty(NULL, &res);
882     expect(InvalidParameter, status);
883
884     /* default is infinite */
885     res = TRUE;
886     status = GdipIsClipEmpty(graphics, &res);
887     expect(Ok, status);
888     expect(FALSE, res);
889
890     GdipDeleteRegion(clip);
891
892     GdipDeleteGraphics(graphics);
893     ReleaseDC(0, hdc);
894 }
895
896 static void test_clear(void)
897 {
898     GpStatus status;
899
900     status = GdipGraphicsClear(NULL, 0xdeadbeef);
901     expect(InvalidParameter, status);
902 }
903
904 static void test_textcontrast(void)
905 {
906     GpStatus status;
907     HDC hdc = GetDC(0);
908     GpGraphics *graphics;
909     UINT contrast;
910
911     status = GdipGetTextContrast(NULL, NULL);
912     expect(InvalidParameter, status);
913
914     status = GdipCreateFromHDC(hdc, &graphics);
915     expect(Ok, status);
916
917     status = GdipGetTextContrast(graphics, NULL);
918     expect(InvalidParameter, status);
919     status = GdipGetTextContrast(graphics, &contrast);
920     expect(4, contrast);
921
922     GdipDeleteGraphics(graphics);
923     ReleaseDC(0, hdc);
924 }
925
926 START_TEST(graphics)
927 {
928     struct GdiplusStartupInput gdiplusStartupInput;
929     ULONG_PTR gdiplusToken;
930
931     gdiplusStartupInput.GdiplusVersion              = 1;
932     gdiplusStartupInput.DebugEventCallback          = NULL;
933     gdiplusStartupInput.SuppressBackgroundThread    = 0;
934     gdiplusStartupInput.SuppressExternalCodecs      = 0;
935
936     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
937
938     test_constructor_destructor();
939     test_save_restore();
940     test_GdipDrawBezierI();
941     test_GdipDrawArc();
942     test_GdipDrawArcI();
943     test_GdipDrawLineI();
944     test_GdipDrawLinesI();
945     test_Get_Release_DC();
946     test_transformpoints();
947     test_get_set_clip();
948     test_isempty();
949     test_clear();
950     test_textcontrast();
951
952     GdiplusShutdown(gdiplusToken);
953 }