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