winhttp, wininet: Load i2d_X509 from libcrypto.so.
[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     HRGN hrgn = CreateRectRgn(0, 0, 10, 10);
490
491     pt[0].X = 10;
492     pt[0].Y = 10;
493     pt[1].X = 20;
494     pt[1].Y = 15;
495     pt[2].X = 40;
496     pt[2].Y = 80;
497     pt[3].X = -20;
498     pt[3].Y = 20;
499     pt[4].X = 50;
500     pt[4].Y = 110;
501
502     for(i = 0; i < 5;i++){
503         ptf[i].X = (REAL)pt[i].X;
504         ptf[i].Y = (REAL)pt[i].Y;
505     }
506
507     rect[0].X = 0;
508     rect[0].Y = 0;
509     rect[0].Width  = 50;
510     rect[0].Height = 70;
511     rect[1].X = 0;
512     rect[1].Y = 0;
513     rect[1].Width  = 10;
514     rect[1].Height = 20;
515
516     for(i = 0; i < 2;i++){
517         rectf[i].X = (REAL)rect[i].X;
518         rectf[i].Y = (REAL)rect[i].Y;
519         rectf[i].Height = (REAL)rect[i].Height;
520         rectf[i].Width  = (REAL)rect[i].Width;
521     }
522
523     GdipCreateMatrix(&m);
524     GdipCreateRegion(&region);
525     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
526     GdipCreatePath(FillModeAlternate, &path);
527     GdipCreateRegion(&clip);
528
529     status = GdipCreateFromHDC(hdc, &graphics);
530     expect(Ok, status);
531     ok(graphics != NULL, "Expected graphics to be initialized\n");
532     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
533     expect(Ok, status);
534
535     /* NULL arguments */
536     status = GdipGetDC(NULL, NULL);
537     expect(InvalidParameter, status);
538     status = GdipGetDC(graphics, NULL);
539     expect(InvalidParameter, status);
540     status = GdipGetDC(NULL, &retdc);
541     expect(InvalidParameter, status);
542
543     status = GdipReleaseDC(NULL, NULL);
544     expect(InvalidParameter, status);
545     status = GdipReleaseDC(graphics, NULL);
546     expect(InvalidParameter, status);
547     status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
548     expect(InvalidParameter, status);
549
550     /* Release without Get */
551     status = GdipReleaseDC(graphics, hdc);
552     expect(InvalidParameter, status);
553
554     retdc = NULL;
555     status = GdipGetDC(graphics, &retdc);
556     expect(Ok, status);
557     ok(retdc == hdc, "Invalid HDC returned\n");
558     /* call it once more */
559     status = GdipGetDC(graphics, &retdc);
560     expect(ObjectBusy, status);
561
562     /* try all Graphics calls here */
563     status = Ok;
564     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
565     expect(ObjectBusy, status); status = Ok;
566     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
567     expect(ObjectBusy, status); status = Ok;
568     status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
569     expect(ObjectBusy, status); status = Ok;
570     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
571     expect(ObjectBusy, status); status = Ok;
572     status = GdipDrawBeziers(graphics, pen, ptf, 5);
573     expect(ObjectBusy, status); status = Ok;
574     status = GdipDrawBeziersI(graphics, pen, pt, 5);
575     expect(ObjectBusy, status); status = Ok;
576     status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
577     expect(ObjectBusy, status); status = Ok;
578     status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
579     expect(ObjectBusy, status); status = Ok;
580     status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
581     expect(ObjectBusy, status); status = Ok;
582     status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
583     expect(ObjectBusy, status); status = Ok;
584     status = GdipDrawCurve(graphics, pen, ptf, 5);
585     expect(ObjectBusy, status); status = Ok;
586     status = GdipDrawCurveI(graphics, pen, pt, 5);
587     expect(ObjectBusy, status); status = Ok;
588     status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
589     expect(ObjectBusy, status); status = Ok;
590     status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
591     expect(ObjectBusy, status); status = Ok;
592     status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
593     expect(ObjectBusy, status); status = Ok;
594     status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
595     expect(ObjectBusy, status); status = Ok;
596     /* GdipDrawImage/GdipDrawImageI */
597     /* GdipDrawImagePointsRect/GdipDrawImagePointsRectI */
598     /* GdipDrawImageRectRect/GdipDrawImageRectRectI */
599     /* GdipDrawImageRect/GdipDrawImageRectI */
600     status = GdipDrawLine(graphics, pen, 0.0, 0.0, 100.0, 200.0);
601     expect(ObjectBusy, status); status = Ok;
602     status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
603     expect(ObjectBusy, status); status = Ok;
604     status = GdipDrawLines(graphics, pen, ptf, 5);
605     expect(ObjectBusy, status); status = Ok;
606     status = GdipDrawLinesI(graphics, pen, pt, 5);
607     expect(ObjectBusy, status); status = Ok;
608     status = GdipDrawPath(graphics, pen, path);
609     expect(ObjectBusy, status); status = Ok;
610     status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
611     expect(ObjectBusy, status); status = Ok;
612     status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
613     expect(ObjectBusy, status); status = Ok;
614     status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
615     expect(ObjectBusy, status); status = Ok;
616     status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
617     expect(ObjectBusy, status); status = Ok;
618     status = GdipDrawRectangles(graphics, pen, rectf, 2);
619     expect(ObjectBusy, status); status = Ok;
620     status = GdipDrawRectanglesI(graphics, pen, rect, 2);
621     expect(ObjectBusy, status); status = Ok;
622     /* GdipDrawString */
623     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
624     expect(ObjectBusy, status); status = Ok;
625     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
626     expect(ObjectBusy, status); status = Ok;
627     status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
628     expect(ObjectBusy, status); status = Ok;
629     status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
630     expect(ObjectBusy, status); status = Ok;
631     status = GdipFillPath(graphics, (GpBrush*)brush, path);
632     expect(ObjectBusy, status); status = Ok;
633     status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
634     expect(ObjectBusy, status); status = Ok;
635     status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
636     expect(ObjectBusy, status); status = Ok;
637     status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
638     expect(ObjectBusy, status); status = Ok;
639     status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
640     expect(ObjectBusy, status); status = Ok;
641     status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
642     expect(ObjectBusy, status); status = Ok;
643     status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
644     expect(ObjectBusy, status); status = Ok;
645     status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
646     expect(ObjectBusy, status); status = Ok;
647     status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
648     expect(ObjectBusy, status); status = Ok;
649     status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
650     expect(ObjectBusy, status); status = Ok;
651     status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
652     expect(ObjectBusy, status); status = Ok;
653     status = GdipFillRegion(graphics, (GpBrush*)brush, region);
654     expect(ObjectBusy, status); status = Ok;
655     status = GdipFlush(graphics, FlushIntentionFlush);
656     expect(ObjectBusy, status); status = Ok;
657     status = GdipGetClipBounds(graphics, rectf);
658     expect(ObjectBusy, status); status = Ok;
659     status = GdipGetClipBoundsI(graphics, rect);
660     expect(ObjectBusy, status); status = Ok;
661     status = GdipGetCompositingMode(graphics, &compmode);
662     expect(ObjectBusy, status); status = Ok;
663     status = GdipGetCompositingQuality(graphics, &quality);
664     expect(ObjectBusy, status); status = Ok;
665     status = GdipGetInterpolationMode(graphics, &intmode);
666     expect(ObjectBusy, status); status = Ok;
667     status = GdipGetNearestColor(graphics, &color);
668     expect(ObjectBusy, status); status = Ok;
669     status = GdipGetPageScale(graphics, &r);
670     expect(ObjectBusy, status); status = Ok;
671     status = GdipGetPageUnit(graphics, &unit);
672     expect(ObjectBusy, status); status = Ok;
673     status = GdipGetPixelOffsetMode(graphics, &offsetmode);
674     expect(ObjectBusy, status); status = Ok;
675     status = GdipGetSmoothingMode(graphics, &smoothmode);
676     expect(ObjectBusy, status); status = Ok;
677     status = GdipGetTextRenderingHint(graphics, &texthint);
678     expect(ObjectBusy, status); status = Ok;
679     status = GdipGetWorldTransform(graphics, m);
680     expect(ObjectBusy, status); status = Ok;
681     status = GdipGraphicsClear(graphics, 0xdeadbeef);
682     expect(ObjectBusy, status); status = Ok;
683     status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
684     expect(ObjectBusy, status); status = Ok;
685     status = GdipIsVisiblePointI(graphics, 0, 0, &res);
686     expect(ObjectBusy, status); status = Ok;
687     /* GdipMeasureCharacterRanges */
688     /* GdipMeasureString */
689     status = GdipResetClip(graphics);
690     expect(ObjectBusy, status); status = Ok;
691     status = GdipResetWorldTransform(graphics);
692     expect(ObjectBusy, status); status = Ok;
693     /* GdipRestoreGraphics */
694     status = GdipRotateWorldTransform(graphics, 15.0, MatrixOrderPrepend);
695     expect(ObjectBusy, status); status = Ok;
696     /*  GdipSaveGraphics */
697     status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
698     expect(ObjectBusy, status); status = Ok;
699     status = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
700     expect(ObjectBusy, status); status = Ok;
701     status = GdipSetCompositingQuality(graphics, CompositingQualityDefault);
702     expect(ObjectBusy, status); status = Ok;
703     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
704     expect(ObjectBusy, status); status = Ok;
705     status = GdipSetPageScale(graphics, 1.0);
706     expect(ObjectBusy, status); status = Ok;
707     status = GdipSetPageUnit(graphics, UnitWorld);
708     expect(ObjectBusy, status); status = Ok;
709     status = GdipSetPixelOffsetMode(graphics, PixelOffsetModeDefault);
710     expect(ObjectBusy, status); status = Ok;
711     status = GdipSetSmoothingMode(graphics, SmoothingModeDefault);
712     expect(ObjectBusy, status); status = Ok;
713     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
714     expect(ObjectBusy, status); status = Ok;
715     status = GdipSetWorldTransform(graphics, m);
716     expect(ObjectBusy, status); status = Ok;
717     status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
718     expect(ObjectBusy, status); status = Ok;
719     status = GdipSetClipHrgn(graphics, hrgn, CombineModeReplace);
720     expect(ObjectBusy, status); status = Ok;
721     status = GdipSetClipPath(graphics, path, CombineModeReplace);
722     expect(ObjectBusy, status); status = Ok;
723     status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
724     expect(ObjectBusy, status); status = Ok;
725     status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
726     expect(ObjectBusy, status); status = Ok;
727     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
728     expect(ObjectBusy, status); status = Ok;
729     status = GdipTranslateClip(graphics, 0.0, 0.0);
730     expect(ObjectBusy, status); status = Ok;
731     status = GdipTranslateClipI(graphics, 0, 0);
732     expect(ObjectBusy, status); status = Ok;
733     status = GdipDrawPolygon(graphics, pen, ptf, 5);
734     expect(ObjectBusy, status); status = Ok;
735     status = GdipDrawPolygonI(graphics, pen, pt, 5);
736     expect(ObjectBusy, status); status = Ok;
737     status = GdipGetDpiX(graphics, &r);
738     expect(ObjectBusy, status); status = Ok;
739     status = GdipGetDpiY(graphics, &r);
740     expect(ObjectBusy, status); status = Ok;
741     status = GdipMultiplyWorldTransform(graphics, m, MatrixOrderPrepend);
742     status = GdipGetClip(graphics, region);
743     expect(ObjectBusy, status); status = Ok;
744     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 5);
745     expect(ObjectBusy, status); status = Ok;
746     /* try to delete before release */
747     status = GdipDeleteGraphics(graphics);
748     expect(ObjectBusy, status);
749
750     status = GdipReleaseDC(graphics, retdc);
751     expect(Ok, status);
752
753     GdipDeletePen(pen);
754     GdipDeleteGraphics(graphics);
755
756     GdipDeletePath(path);
757     GdipDeleteBrush((GpBrush*)brush);
758     GdipDeleteRegion(region);
759     GdipDeleteMatrix(m);
760     DeleteObject(hrgn);
761
762     ReleaseDC(0, hdc);
763 }
764
765 static void test_transformpoints(void)
766 {
767     GpStatus status;
768     GpGraphics *graphics = NULL;
769     HDC hdc = GetDC(0);
770     GpPointF ptf[5];
771     INT i;
772
773     status = GdipCreateFromHDC(hdc, &graphics);
774     expect(Ok, status);
775
776     for(i = 0; i < 5; i++){
777         ptf[i].X = 200.0 + i * 50.0 * (i % 2);
778         ptf[i].Y = 200.0 + i * 50.0 * !(i % 2);
779     }
780
781     /* NULL arguments */
782     status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
783     expect(InvalidParameter, status);
784     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
785     expect(InvalidParameter, status);
786     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 0);
787     expect(InvalidParameter, status);
788     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1);
789     expect(InvalidParameter, status);
790
791     GdipDeleteGraphics(graphics);
792     ReleaseDC(0, hdc);
793 }
794
795 static void test_get_set_clip(void)
796 {
797     GpStatus status;
798     GpGraphics *graphics = NULL;
799     HDC hdc = GetDC(0);
800     GpRegion *clip;
801     GpRectF rect;
802     BOOL res;
803
804     status = GdipCreateFromHDC(hdc, &graphics);
805     expect(Ok, status);
806
807     rect.X = rect.Y = 0.0;
808     rect.Height = rect.Width = 100.0;
809
810     status = GdipCreateRegionRect(&rect, &clip);
811
812     /* NULL arguments */
813     status = GdipGetClip(NULL, NULL);
814     expect(InvalidParameter, status);
815     status = GdipGetClip(graphics, NULL);
816     expect(InvalidParameter, status);
817     status = GdipGetClip(NULL, clip);
818     expect(InvalidParameter, status);
819
820     status = GdipSetClipRegion(NULL, NULL, CombineModeReplace);
821     expect(InvalidParameter, status);
822     status = GdipSetClipRegion(graphics, NULL, CombineModeReplace);
823     expect(InvalidParameter, status);
824
825     status = GdipSetClipPath(NULL, NULL, CombineModeReplace);
826     expect(InvalidParameter, status);
827     status = GdipSetClipPath(graphics, NULL, CombineModeReplace);
828     expect(InvalidParameter, status);
829
830     res = FALSE;
831     status = GdipGetClip(graphics, clip);
832     expect(Ok, status);
833     status = GdipIsInfiniteRegion(clip, graphics, &res);
834     expect(Ok, status);
835     expect(TRUE, res);
836
837     /* remains infinite after reset */
838     res = FALSE;
839     status = GdipResetClip(graphics);
840     expect(Ok, status);
841     status = GdipGetClip(graphics, clip);
842     expect(Ok, status);
843     status = GdipIsInfiniteRegion(clip, graphics, &res);
844     expect(Ok, status);
845     expect(TRUE, res);
846
847     /* set to empty and then reset to infinite */
848     status = GdipSetEmpty(clip);
849     expect(Ok, status);
850     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
851     expect(Ok, status);
852
853     status = GdipGetClip(graphics, clip);
854     expect(Ok, status);
855     res = FALSE;
856     status = GdipIsEmptyRegion(clip, graphics, &res);
857     expect(Ok, status);
858     expect(TRUE, res);
859     status = GdipResetClip(graphics);
860     expect(Ok, status);
861     status = GdipGetClip(graphics, clip);
862     expect(Ok, status);
863     res = FALSE;
864     status = GdipIsInfiniteRegion(clip, graphics, &res);
865     expect(Ok, status);
866     expect(TRUE, res);
867
868     GdipDeleteRegion(clip);
869
870     GdipDeleteGraphics(graphics);
871     ReleaseDC(0, hdc);
872 }
873
874 static void test_isempty(void)
875 {
876     GpStatus status;
877     GpGraphics *graphics = NULL;
878     HDC hdc = GetDC(0);
879     GpRegion *clip;
880     BOOL res;
881
882     status = GdipCreateFromHDC(hdc, &graphics);
883     expect(Ok, status);
884
885     status = GdipCreateRegion(&clip);
886     expect(Ok, status);
887
888     /* NULL */
889     status = GdipIsClipEmpty(NULL, NULL);
890     expect(InvalidParameter, status);
891     status = GdipIsClipEmpty(graphics, NULL);
892     expect(InvalidParameter, status);
893     status = GdipIsClipEmpty(NULL, &res);
894     expect(InvalidParameter, status);
895
896     /* default is infinite */
897     res = TRUE;
898     status = GdipIsClipEmpty(graphics, &res);
899     expect(Ok, status);
900     expect(FALSE, res);
901
902     GdipDeleteRegion(clip);
903
904     GdipDeleteGraphics(graphics);
905     ReleaseDC(0, hdc);
906 }
907
908 static void test_clear(void)
909 {
910     GpStatus status;
911
912     status = GdipGraphicsClear(NULL, 0xdeadbeef);
913     expect(InvalidParameter, status);
914 }
915
916 static void test_textcontrast(void)
917 {
918     GpStatus status;
919     HDC hdc = GetDC(0);
920     GpGraphics *graphics;
921     UINT contrast;
922
923     status = GdipGetTextContrast(NULL, NULL);
924     expect(InvalidParameter, status);
925
926     status = GdipCreateFromHDC(hdc, &graphics);
927     expect(Ok, status);
928
929     status = GdipGetTextContrast(graphics, NULL);
930     expect(InvalidParameter, status);
931     status = GdipGetTextContrast(graphics, &contrast);
932     expect(4, contrast);
933
934     GdipDeleteGraphics(graphics);
935     ReleaseDC(0, hdc);
936 }
937
938 START_TEST(graphics)
939 {
940     struct GdiplusStartupInput gdiplusStartupInput;
941     ULONG_PTR gdiplusToken;
942
943     gdiplusStartupInput.GdiplusVersion              = 1;
944     gdiplusStartupInput.DebugEventCallback          = NULL;
945     gdiplusStartupInput.SuppressBackgroundThread    = 0;
946     gdiplusStartupInput.SuppressExternalCodecs      = 0;
947
948     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
949
950     test_constructor_destructor();
951     test_save_restore();
952     test_GdipDrawBezierI();
953     test_GdipDrawArc();
954     test_GdipDrawArcI();
955     test_GdipDrawLineI();
956     test_GdipDrawLinesI();
957     test_Get_Release_DC();
958     test_transformpoints();
959     test_get_set_clip();
960     test_isempty();
961     test_clear();
962     test_textcontrast();
963
964     GdiplusShutdown(gdiplusToken);
965 }