po: Update French translation.
[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 #include <math.h>
26
27 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
28 #define expectf_(expected, got, precision) ok(fabs(expected - got) < precision, "Expected %.2f, got %.2f\n", expected, got)
29 #define expectf(expected, got) expectf_(expected, got, 0.0001)
30 #define TABLE_LEN (23)
31
32 static HWND hwnd;
33
34 static void test_constructor_destructor(void)
35 {
36     GpStatus stat;
37     GpGraphics *graphics = NULL;
38     HDC hdc = GetDC( hwnd );
39
40     stat = GdipCreateFromHDC(NULL, &graphics);
41     expect(OutOfMemory, stat);
42     stat = GdipDeleteGraphics(graphics);
43     expect(InvalidParameter, stat);
44
45     stat = GdipCreateFromHDC(hdc, &graphics);
46     expect(Ok, stat);
47     stat = GdipDeleteGraphics(graphics);
48     expect(Ok, stat);
49
50     stat = GdipCreateFromHWND(NULL, &graphics);
51     expect(Ok, stat);
52     stat = GdipDeleteGraphics(graphics);
53     expect(Ok, stat);
54
55     stat = GdipCreateFromHWNDICM(NULL, &graphics);
56     expect(Ok, stat);
57     stat = GdipDeleteGraphics(graphics);
58     expect(Ok, stat);
59
60     stat = GdipDeleteGraphics(NULL);
61     expect(InvalidParameter, stat);
62     ReleaseDC(hwnd, hdc);
63 }
64
65 typedef struct node{
66     GraphicsState data;
67     struct node * next;
68 } node;
69
70 /* Linked list prepend function. */
71 static void log_state(GraphicsState data, node ** log)
72 {
73     node * new_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(node));
74
75     new_entry->data = data;
76     new_entry->next = *log;
77     *log = new_entry;
78 }
79
80 /* Checks if there are duplicates in the list, and frees it. */
81 static void check_no_duplicates(node * log)
82 {
83     INT dups = 0;
84     node * temp = NULL;
85     node * temp2 = NULL;
86     node * orig = log;
87
88     if(!log)
89         goto end;
90
91     do{
92         temp = log;
93         while((temp = temp->next)){
94             if(log->data == temp->data){
95                 dups++;
96                 break;
97             }
98             if(dups > 0)
99                 break;
100         }
101     }while((log = log->next));
102
103     temp = orig;
104     do{
105         temp2 = temp->next;
106         HeapFree(GetProcessHeap(), 0, temp);
107         temp = temp2;
108     }while(temp);
109
110 end:
111     expect(0, dups);
112 }
113
114 static void test_save_restore(void)
115 {
116     GpStatus stat;
117     GraphicsState state_a, state_b, state_c;
118     InterpolationMode mode;
119     GpGraphics *graphics1, *graphics2;
120     node * state_log = NULL;
121     HDC hdc = GetDC( hwnd );
122     state_a = state_b = state_c = 0xdeadbeef;
123
124     /* Invalid saving. */
125     GdipCreateFromHDC(hdc, &graphics1);
126     stat = GdipSaveGraphics(graphics1, NULL);
127     expect(InvalidParameter, stat);
128     stat = GdipSaveGraphics(NULL, &state_a);
129     expect(InvalidParameter, stat);
130     GdipDeleteGraphics(graphics1);
131
132     log_state(state_a, &state_log);
133
134     /* Basic save/restore. */
135     GdipCreateFromHDC(hdc, &graphics1);
136     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
137     stat = GdipSaveGraphics(graphics1, &state_a);
138     expect(Ok, stat);
139     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
140     stat = GdipRestoreGraphics(graphics1, state_a);
141     expect(Ok, stat);
142     GdipGetInterpolationMode(graphics1, &mode);
143     expect(InterpolationModeBilinear, mode);
144     GdipDeleteGraphics(graphics1);
145
146     log_state(state_a, &state_log);
147
148     /* Restoring garbage doesn't affect saves. */
149     GdipCreateFromHDC(hdc, &graphics1);
150     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
151     GdipSaveGraphics(graphics1, &state_a);
152     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
153     GdipSaveGraphics(graphics1, &state_b);
154     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
155     stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
156     expect(Ok, stat);
157     GdipRestoreGraphics(graphics1, state_b);
158     GdipGetInterpolationMode(graphics1, &mode);
159     expect(InterpolationModeBicubic, mode);
160     GdipRestoreGraphics(graphics1, state_a);
161     GdipGetInterpolationMode(graphics1, &mode);
162     expect(InterpolationModeBilinear, mode);
163     GdipDeleteGraphics(graphics1);
164
165     log_state(state_a, &state_log);
166     log_state(state_b, &state_log);
167
168     /* Restoring older state invalidates newer saves (but not older saves). */
169     GdipCreateFromHDC(hdc, &graphics1);
170     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
171     GdipSaveGraphics(graphics1, &state_a);
172     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
173     GdipSaveGraphics(graphics1, &state_b);
174     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
175     GdipSaveGraphics(graphics1, &state_c);
176     GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
177     GdipRestoreGraphics(graphics1, state_b);
178     GdipGetInterpolationMode(graphics1, &mode);
179     expect(InterpolationModeBicubic, mode);
180     GdipRestoreGraphics(graphics1, state_c);
181     GdipGetInterpolationMode(graphics1, &mode);
182     expect(InterpolationModeBicubic, mode);
183     GdipRestoreGraphics(graphics1, state_a);
184     GdipGetInterpolationMode(graphics1, &mode);
185     expect(InterpolationModeBilinear, mode);
186     GdipDeleteGraphics(graphics1);
187
188     log_state(state_a, &state_log);
189     log_state(state_b, &state_log);
190     log_state(state_c, &state_log);
191
192     /* Restoring older save from one graphics object does not invalidate
193      * newer save from other graphics object. */
194     GdipCreateFromHDC(hdc, &graphics1);
195     GdipCreateFromHDC(hdc, &graphics2);
196     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
197     GdipSaveGraphics(graphics1, &state_a);
198     GdipSetInterpolationMode(graphics2, InterpolationModeBicubic);
199     GdipSaveGraphics(graphics2, &state_b);
200     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
201     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
202     GdipRestoreGraphics(graphics1, state_a);
203     GdipGetInterpolationMode(graphics1, &mode);
204     expect(InterpolationModeBilinear, mode);
205     GdipRestoreGraphics(graphics2, state_b);
206     GdipGetInterpolationMode(graphics2, &mode);
207     expect(InterpolationModeBicubic, mode);
208     GdipDeleteGraphics(graphics1);
209     GdipDeleteGraphics(graphics2);
210
211     /* You can't restore a state to a graphics object that didn't save it. */
212     GdipCreateFromHDC(hdc, &graphics1);
213     GdipCreateFromHDC(hdc, &graphics2);
214     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
215     GdipSaveGraphics(graphics1, &state_a);
216     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
217     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
218     GdipRestoreGraphics(graphics2, state_a);
219     GdipGetInterpolationMode(graphics2, &mode);
220     expect(InterpolationModeNearestNeighbor, mode);
221     GdipDeleteGraphics(graphics1);
222     GdipDeleteGraphics(graphics2);
223
224     log_state(state_a, &state_log);
225
226     /* The same state value should never be returned twice. */
227     todo_wine
228         check_no_duplicates(state_log);
229
230     ReleaseDC(hwnd, hdc);
231 }
232
233 static void test_GdipFillClosedCurve2(void)
234 {
235     GpStatus status;
236     GpGraphics *graphics = NULL;
237     GpSolidFill *brush = NULL;
238     HDC hdc = GetDC( hwnd );
239     GpPointF points[3];
240
241     points[0].X = 0;
242     points[0].Y = 0;
243
244     points[1].X = 40;
245     points[1].Y = 20;
246
247     points[2].X = 10;
248     points[2].Y = 40;
249
250     /* make a graphics object and brush object */
251     ok(hdc != NULL, "Expected HDC to be initialized\n");
252
253     status = GdipCreateFromHDC(hdc, &graphics);
254     expect(Ok, status);
255     ok(graphics != NULL, "Expected graphics to be initialized\n");
256
257     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
258
259     /* InvalidParameter cases: null graphics, null brush, null points */
260     status = GdipFillClosedCurve2(NULL, NULL, NULL, 3, 0.5, FillModeAlternate);
261     expect(InvalidParameter, status);
262
263     status = GdipFillClosedCurve2(graphics, NULL, NULL, 3, 0.5, FillModeAlternate);
264     expect(InvalidParameter, status);
265
266     status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
267     expect(InvalidParameter, status);
268
269     status = GdipFillClosedCurve2(NULL, NULL, points, 3, 0.5, FillModeAlternate);
270     expect(InvalidParameter, status);
271
272     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
273     expect(InvalidParameter, status);
274
275     status = GdipFillClosedCurve2(graphics, NULL, points, 3, 0.5, FillModeAlternate);
276     expect(InvalidParameter, status);
277
278     status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
279     expect(InvalidParameter, status);
280
281     /* InvalidParameter cases: invalid count */
282     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
283     expect(InvalidParameter, status);
284
285     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
286     expect(InvalidParameter, status);
287
288     /* Valid test cases */
289     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
290     expect(Ok, status);
291
292     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
293     expect(Ok, status);
294
295     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
296     expect(Ok, status);
297
298     GdipDeleteGraphics(graphics);
299     GdipDeleteBrush((GpBrush*)brush);
300
301     ReleaseDC(hwnd, hdc);
302 }
303
304 static void test_GdipFillClosedCurve2I(void)
305 {
306     GpStatus status;
307     GpGraphics *graphics = NULL;
308     GpSolidFill *brush = NULL;
309     HDC hdc = GetDC( hwnd );
310     GpPoint points[3];
311
312     points[0].X = 0;
313     points[0].Y = 0;
314
315     points[1].X = 40;
316     points[1].Y = 20;
317
318     points[2].X = 10;
319     points[2].Y = 40;
320
321     /* make a graphics object and brush object */
322     ok(hdc != NULL, "Expected HDC to be initialized\n");
323
324     status = GdipCreateFromHDC(hdc, &graphics);
325     expect(Ok, status);
326     ok(graphics != NULL, "Expected graphics to be initialized\n");
327
328     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
329
330     /* InvalidParameter cases: null graphics, null brush */
331     /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
332              when points == NULL, so don't test this condition */
333     status = GdipFillClosedCurve2I(NULL, NULL, points, 3, 0.5, FillModeAlternate);
334     expect(InvalidParameter, status);
335
336     status = GdipFillClosedCurve2I(graphics, NULL, points, 3, 0.5, FillModeAlternate);
337     expect(InvalidParameter, status);
338
339     status = GdipFillClosedCurve2I(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
340     expect(InvalidParameter, status);
341
342     /* InvalidParameter cases: invalid count */
343     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
344     expect(InvalidParameter, status);
345
346     /* OutOfMemory cases: large (unsigned) int */
347     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
348     expect(OutOfMemory, status);
349
350     /* Valid test cases */
351     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
352     expect(Ok, status);
353
354     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
355     expect(Ok, status);
356
357     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
358     expect(Ok, status);
359
360     GdipDeleteGraphics(graphics);
361     GdipDeleteBrush((GpBrush*)brush);
362
363     ReleaseDC(hwnd, hdc);
364 }
365
366 static void test_GdipDrawArc(void)
367 {
368     GpStatus status;
369     GpGraphics *graphics = NULL;
370     GpPen *pen = NULL;
371     HDC hdc = GetDC( hwnd );
372
373     /* make a graphics object and pen object */
374     ok(hdc != NULL, "Expected HDC to be initialized\n");
375
376     status = GdipCreateFromHDC(hdc, &graphics);
377     expect(Ok, status);
378     ok(graphics != NULL, "Expected graphics to be initialized\n");
379
380     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
381     expect(Ok, status);
382     ok(pen != NULL, "Expected pen to be initialized\n");
383
384     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
385     status = GdipDrawArc(NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
386     expect(InvalidParameter, status);
387
388     status = GdipDrawArc(graphics, NULL, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
389     expect(InvalidParameter, status);
390
391     status = GdipDrawArc(NULL, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
392     expect(InvalidParameter, status);
393
394     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
395     expect(InvalidParameter, status);
396
397     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
398     expect(InvalidParameter, status);
399
400     /* successful case */
401     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
402     expect(Ok, status);
403
404     GdipDeletePen(pen);
405     GdipDeleteGraphics(graphics);
406
407     ReleaseDC(hwnd, hdc);
408 }
409
410 static void test_GdipDrawArcI(void)
411 {
412     GpStatus status;
413     GpGraphics *graphics = NULL;
414     GpPen *pen = NULL;
415     HDC hdc = GetDC( hwnd );
416
417     /* make a graphics object and pen object */
418     ok(hdc != NULL, "Expected HDC to be initialized\n");
419
420     status = GdipCreateFromHDC(hdc, &graphics);
421     expect(Ok, status);
422     ok(graphics != NULL, "Expected graphics to be initialized\n");
423
424     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
425     expect(Ok, status);
426     ok(pen != NULL, "Expected pen to be initialized\n");
427
428     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
429     status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
430     expect(InvalidParameter, status);
431
432     status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
433     expect(InvalidParameter, status);
434
435     status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
436     expect(InvalidParameter, status);
437
438     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
439     expect(InvalidParameter, status);
440
441     status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
442     expect(InvalidParameter, status);
443
444     /* successful case */
445     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
446     expect(Ok, status);
447
448     GdipDeletePen(pen);
449     GdipDeleteGraphics(graphics);
450
451     ReleaseDC(hwnd, hdc);
452 }
453
454 static void test_BeginContainer2(void)
455 {
456     GpMatrix *transform;
457     GpRectF clip;
458     REAL defClip[] = {5, 10, 15, 20};
459     REAL elems[6], defTrans[] = {1, 2, 3, 4, 5, 6};
460     GraphicsContainer cont1, cont2, cont3, cont4;
461     CompositingQuality compqual, defCompqual = CompositingQualityHighSpeed;
462     CompositingMode compmode, defCompmode = CompositingModeSourceOver;
463     InterpolationMode interp, defInterp = InterpolationModeHighQualityBicubic;
464     REAL scale, defScale = 17;
465     GpUnit unit, defUnit = UnitPixel;
466     PixelOffsetMode offsetmode, defOffsetmode = PixelOffsetModeHighSpeed;
467     SmoothingMode smoothmode, defSmoothmode = SmoothingModeAntiAlias;
468     UINT contrast, defContrast = 5;
469     TextRenderingHint texthint, defTexthint = TextRenderingHintAntiAlias;
470
471     GpStatus status;
472     GpGraphics *graphics = NULL;
473     HDC hdc = GetDC( hwnd );
474
475     ok(hdc != NULL, "Expected HDC to be initialized\n");
476
477     status = GdipCreateFromHDC(hdc, &graphics);
478     expect(Ok, status);
479     ok(graphics != NULL, "Expected graphics to be initialized\n");
480
481     /* null graphics, null container */
482     status = GdipBeginContainer2(NULL, &cont1);
483     expect(InvalidParameter, status);
484
485     status = GdipBeginContainer2(graphics, NULL);
486     expect(InvalidParameter, status);
487
488     status = GdipEndContainer(NULL, cont1);
489     expect(InvalidParameter, status);
490
491     /* test all quality-related values */
492     GdipSetCompositingMode(graphics, defCompmode);
493     GdipSetCompositingQuality(graphics, defCompqual);
494     GdipSetInterpolationMode(graphics, defInterp);
495     GdipSetPageScale(graphics, defScale);
496     GdipSetPageUnit(graphics, defUnit);
497     GdipSetPixelOffsetMode(graphics, defOffsetmode);
498     GdipSetSmoothingMode(graphics, defSmoothmode);
499     GdipSetTextContrast(graphics, defContrast);
500     GdipSetTextRenderingHint(graphics, defTexthint);
501
502     status = GdipBeginContainer2(graphics, &cont1);
503     expect(Ok, status);
504
505     GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
506     GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
507     GdipSetInterpolationMode(graphics, InterpolationModeBilinear);
508     GdipSetPageScale(graphics, 10);
509     GdipSetPageUnit(graphics, UnitDocument);
510     GdipSetPixelOffsetMode(graphics, PixelOffsetModeHalf);
511     GdipSetSmoothingMode(graphics, SmoothingModeNone);
512     GdipSetTextContrast(graphics, 7);
513     GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit);
514
515     status = GdipEndContainer(graphics, cont1);
516     expect(Ok, status);
517
518     GdipGetCompositingMode(graphics, &compmode);
519     ok(defCompmode == compmode, "Expected Compositing Mode to be restored to %d, got %d\n", defCompmode, compmode);
520
521     GdipGetCompositingQuality(graphics, &compqual);
522     ok(defCompqual == compqual, "Expected Compositing Quality to be restored to %d, got %d\n", defCompqual, compqual);
523
524     GdipGetInterpolationMode(graphics, &interp);
525     ok(defInterp == interp, "Expected Interpolation Mode to be restored to %d, got %d\n", defInterp, interp);
526
527     GdipGetPageScale(graphics, &scale);
528     ok(fabs(defScale - scale) < 0.0001, "Expected Page Scale to be restored to %f, got %f\n", defScale, scale);
529
530     GdipGetPageUnit(graphics, &unit);
531     ok(defUnit == unit, "Expected Page Unit to be restored to %d, got %d\n", defUnit, unit);
532
533     GdipGetPixelOffsetMode(graphics, &offsetmode);
534     ok(defOffsetmode == offsetmode, "Expected Pixel Offset Mode to be restored to %d, got %d\n", defOffsetmode, offsetmode);
535
536     GdipGetSmoothingMode(graphics, &smoothmode);
537     ok(defSmoothmode == smoothmode, "Expected Smoothing Mode to be restored to %d, got %d\n", defSmoothmode, smoothmode);
538
539     GdipGetTextContrast(graphics, &contrast);
540     ok(defContrast == contrast, "Expected Text Contrast to be restored to %d, got %d\n", defContrast, contrast);
541
542     GdipGetTextRenderingHint(graphics, &texthint);
543     ok(defTexthint == texthint, "Expected Text Hint to be restored to %d, got %d\n", defTexthint, texthint);
544
545     /* test world transform */
546     status = GdipBeginContainer2(graphics, &cont1);
547     expect(Ok, status);
548
549     status = GdipCreateMatrix2(defTrans[0], defTrans[1], defTrans[2], defTrans[3],
550             defTrans[4], defTrans[5], &transform);
551     expect(Ok, status);
552     GdipSetWorldTransform(graphics, transform);
553     GdipDeleteMatrix(transform);
554     transform = NULL;
555
556     status = GdipBeginContainer2(graphics, &cont2);
557     expect(Ok, status);
558
559     status = GdipCreateMatrix2(10, 20, 30, 40, 50, 60, &transform);
560     expect(Ok, status);
561     GdipSetWorldTransform(graphics, transform);
562     GdipDeleteMatrix(transform);
563     transform = NULL;
564
565     status = GdipEndContainer(graphics, cont2);
566     expect(Ok, status);
567
568     status = GdipCreateMatrix(&transform);
569     expect(Ok, status);
570     GdipGetWorldTransform(graphics, transform);
571     GdipGetMatrixElements(transform, elems);
572     ok(fabs(defTrans[0] - elems[0]) < 0.0001 &&
573             fabs(defTrans[1] - elems[1]) < 0.0001 &&
574             fabs(defTrans[2] - elems[2]) < 0.0001 &&
575             fabs(defTrans[3] - elems[3]) < 0.0001 &&
576             fabs(defTrans[4] - elems[4]) < 0.0001 &&
577             fabs(defTrans[5] - elems[5]) < 0.0001,
578             "Expected World Transform Matrix to be restored to [%f, %f, %f, %f, %f, %f], got [%f, %f, %f, %f, %f, %f]\n",
579             defTrans[0], defTrans[1], defTrans[2], defTrans[3], defTrans[4], defTrans[5],
580             elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
581     GdipDeleteMatrix(transform);
582     transform = NULL;
583
584     status = GdipEndContainer(graphics, cont1);
585     expect(Ok, status);
586
587     /* test clipping */
588     status = GdipBeginContainer2(graphics, &cont1);
589     expect(Ok, status);
590
591     GdipSetClipRect(graphics, defClip[0], defClip[1], defClip[2], defClip[3], CombineModeReplace);
592
593     status = GdipBeginContainer2(graphics, &cont2);
594     expect(Ok, status);
595
596     GdipSetClipRect(graphics, 2, 4, 6, 8, CombineModeReplace);
597
598     status = GdipEndContainer(graphics, cont2);
599     expect(Ok, status);
600
601     GdipGetClipBounds(graphics, &clip);
602     ok(fabs(defClip[0] - clip.X) < 0.0001 &&
603             fabs(defClip[1] - clip.Y) < 0.0001 &&
604             fabs(defClip[2] - clip.Width) < 0.0001 &&
605             fabs(defClip[3] - clip.Height) < 0.0001,
606             "Expected Clipping Rectangle to be restored to [%f, %f, %f, %f], got [%f, %f, %f, %f]\n",
607             defClip[0], defClip[1], defClip[2], defClip[3],
608             clip.X, clip.Y, clip.Width, clip.Height);
609
610     status = GdipEndContainer(graphics, cont1);
611     expect(Ok, status);
612
613     /* nesting */
614     status = GdipBeginContainer2(graphics, &cont1);
615     expect(Ok, status);
616
617     status = GdipBeginContainer2(graphics, &cont2);
618     expect(Ok, status);
619
620     status = GdipBeginContainer2(graphics, &cont3);
621     expect(Ok, status);
622
623     status = GdipEndContainer(graphics, cont3);
624     expect(Ok, status);
625
626     status = GdipBeginContainer2(graphics, &cont4);
627     expect(Ok, status);
628
629     status = GdipEndContainer(graphics, cont4);
630     expect(Ok, status);
631
632     /* skip cont2 */
633     status = GdipEndContainer(graphics, cont1);
634     expect(Ok, status);
635
636     /* end an already-ended container */
637     status = GdipEndContainer(graphics, cont1);
638     expect(Ok, status);
639
640     GdipDeleteGraphics(graphics);
641     ReleaseDC(hwnd, hdc);
642 }
643
644 static void test_GdipDrawBezierI(void)
645 {
646     GpStatus status;
647     GpGraphics *graphics = NULL;
648     GpPen *pen = NULL;
649     HDC hdc = GetDC( hwnd );
650
651     /* make a graphics object and pen object */
652     ok(hdc != NULL, "Expected HDC to be initialized\n");
653
654     status = GdipCreateFromHDC(hdc, &graphics);
655     expect(Ok, status);
656     ok(graphics != NULL, "Expected graphics to be initialized\n");
657
658     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
659     expect(Ok, status);
660     ok(pen != NULL, "Expected pen to be initialized\n");
661
662     /* InvalidParameter cases: null graphics, null pen */
663     status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
664     expect(InvalidParameter, status);
665
666     status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
667     expect(InvalidParameter, status);
668
669     status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
670     expect(InvalidParameter, status);
671
672     /* successful case */
673     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
674     expect(Ok, status);
675
676     GdipDeletePen(pen);
677     GdipDeleteGraphics(graphics);
678
679     ReleaseDC(hwnd, hdc);
680 }
681
682 static void test_GdipDrawCurve3(void)
683 {
684     GpStatus status;
685     GpGraphics *graphics = NULL;
686     GpPen *pen = NULL;
687     HDC hdc = GetDC( hwnd );
688     GpPointF points[3];
689
690     points[0].X = 0;
691     points[0].Y = 0;
692
693     points[1].X = 40;
694     points[1].Y = 20;
695
696     points[2].X = 10;
697     points[2].Y = 40;
698
699     /* make a graphics object and pen object */
700     ok(hdc != NULL, "Expected HDC to be initialized\n");
701
702     status = GdipCreateFromHDC(hdc, &graphics);
703     expect(Ok, status);
704     ok(graphics != NULL, "Expected graphics to be initialized\n");
705
706     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
707     expect(Ok, status);
708     ok(pen != NULL, "Expected pen to be initialized\n");
709
710     /* InvalidParameter cases: null graphics, null pen */
711     status = GdipDrawCurve3(NULL, NULL, points, 3, 0, 2, 1);
712     expect(InvalidParameter, status);
713
714     status = GdipDrawCurve3(graphics, NULL, points, 3, 0, 2, 1);
715     expect(InvalidParameter, status);
716
717     status = GdipDrawCurve3(NULL, pen, points, 3, 0, 2, 1);
718     expect(InvalidParameter, status);
719
720     /* InvalidParameter cases: invalid count */
721     status = GdipDrawCurve3(graphics, pen, points, -1, 0, 2, 1);
722     expect(InvalidParameter, status);
723
724     status = GdipDrawCurve3(graphics, pen, points, 0, 0, 2, 1);
725     expect(InvalidParameter, status);
726
727     status = GdipDrawCurve3(graphics, pen, points, 1, 0, 0, 1);
728     expect(InvalidParameter, status);
729
730     status = GdipDrawCurve3(graphics, pen, points, 3, 4, 2, 1);
731     expect(InvalidParameter, status);
732
733     /* InvalidParameter cases: invalid number of segments */
734     status = GdipDrawCurve3(graphics, pen, points, 3, 0, -1, 1);
735     expect(InvalidParameter, status);
736
737     status = GdipDrawCurve3(graphics, pen, points, 3, 1, 2, 1);
738     expect(InvalidParameter, status);
739
740     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 2, 1);
741     expect(InvalidParameter, status);
742
743     /* Valid test cases */
744     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, 1);
745     expect(Ok, status);
746
747     status = GdipDrawCurve3(graphics, pen, points, 3, 0, 2, 2);
748     expect(Ok, status);
749
750     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, -2);
751     expect(Ok, status);
752
753     status = GdipDrawCurve3(graphics, pen, points, 3, 1, 1, 0);
754     expect(Ok, status);
755
756     GdipDeletePen(pen);
757     GdipDeleteGraphics(graphics);
758
759     ReleaseDC(hwnd, hdc);
760 }
761
762 static void test_GdipDrawCurve3I(void)
763 {
764     GpStatus status;
765     GpGraphics *graphics = NULL;
766     GpPen *pen = NULL;
767     HDC hdc = GetDC( hwnd );
768     GpPoint points[3];
769
770     points[0].X = 0;
771     points[0].Y = 0;
772
773     points[1].X = 40;
774     points[1].Y = 20;
775
776     points[2].X = 10;
777     points[2].Y = 40;
778
779     /* make a graphics object and pen object */
780     ok(hdc != NULL, "Expected HDC to be initialized\n");
781
782     status = GdipCreateFromHDC(hdc, &graphics);
783     expect(Ok, status);
784     ok(graphics != NULL, "Expected graphics to be initialized\n");
785
786     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
787     expect(Ok, status);
788     ok(pen != NULL, "Expected pen to be initialized\n");
789
790     /* InvalidParameter cases: null graphics, null pen */
791     status = GdipDrawCurve3I(NULL, NULL, points, 3, 0, 2, 1);
792     expect(InvalidParameter, status);
793
794     status = GdipDrawCurve3I(graphics, NULL, points, 3, 0, 2, 1);
795     expect(InvalidParameter, status);
796
797     status = GdipDrawCurve3I(NULL, pen, points, 3, 0, 2, 1);
798     expect(InvalidParameter, status);
799
800     /* InvalidParameter cases: invalid count */
801     status = GdipDrawCurve3I(graphics, pen, points, -1, -1, -1, 1);
802     expect(OutOfMemory, status);
803
804     status = GdipDrawCurve3I(graphics, pen, points, 0, 0, 2, 1);
805     expect(InvalidParameter, status);
806
807     status = GdipDrawCurve3I(graphics, pen, points, 1, 0, 0, 1);
808     expect(InvalidParameter, status);
809
810     status = GdipDrawCurve3I(graphics, pen, points, 3, 4, 2, 1);
811     expect(InvalidParameter, status);
812
813     /* InvalidParameter cases: invalid number of segments */
814     status = GdipDrawCurve3I(graphics, pen, points, 3, 0, -1, 1);
815     expect(InvalidParameter, status);
816
817     status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 2, 1);
818     expect(InvalidParameter, status);
819
820     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 2, 1);
821     expect(InvalidParameter, status);
822
823     /* Valid test cases */
824     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, 1);
825     expect(Ok, status);
826
827     status = GdipDrawCurve3I(graphics, pen, points, 3, 0, 2, 2);
828     expect(Ok, status);
829
830     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, -2);
831     expect(Ok, status);
832
833     status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 1, 0);
834     expect(Ok, status);
835
836     GdipDeletePen(pen);
837     GdipDeleteGraphics(graphics);
838
839     ReleaseDC(hwnd, hdc);
840 }
841
842 static void test_GdipDrawCurve2(void)
843 {
844     GpStatus status;
845     GpGraphics *graphics = NULL;
846     GpPen *pen = NULL;
847     HDC hdc = GetDC( hwnd );
848     GpPointF points[3];
849
850     points[0].X = 0;
851     points[0].Y = 0;
852
853     points[1].X = 40;
854     points[1].Y = 20;
855
856     points[2].X = 10;
857     points[2].Y = 40;
858
859     /* make a graphics object and pen object */
860     ok(hdc != NULL, "Expected HDC to be initialized\n");
861
862     status = GdipCreateFromHDC(hdc, &graphics);
863     expect(Ok, status);
864     ok(graphics != NULL, "Expected graphics to be initialized\n");
865
866     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
867     expect(Ok, status);
868     ok(pen != NULL, "Expected pen to be initialized\n");
869
870     /* InvalidParameter cases: null graphics, null pen */
871     status = GdipDrawCurve2(NULL, NULL, points, 3, 1);
872     expect(InvalidParameter, status);
873
874     status = GdipDrawCurve2(graphics, NULL, points, 3, 1);
875     expect(InvalidParameter, status);
876
877     status = GdipDrawCurve2(NULL, pen, points, 3, 1);
878     expect(InvalidParameter, status);
879
880     /* InvalidParameter cases: invalid count */
881     status = GdipDrawCurve2(graphics, pen, points, -1, 1);
882     expect(InvalidParameter, status);
883
884     status = GdipDrawCurve2(graphics, pen, points, 0, 1);
885     expect(InvalidParameter, status);
886
887     status = GdipDrawCurve2(graphics, pen, points, 1, 1);
888     expect(InvalidParameter, status);
889
890     /* Valid test cases */
891     status = GdipDrawCurve2(graphics, pen, points, 2, 1);
892     expect(Ok, status);
893
894     status = GdipDrawCurve2(graphics, pen, points, 3, 2);
895     expect(Ok, status);
896
897     status = GdipDrawCurve2(graphics, pen, points, 3, -2);
898     expect(Ok, status);
899
900     status = GdipDrawCurve2(graphics, pen, points, 3, 0);
901     expect(Ok, status);
902
903     GdipDeletePen(pen);
904     GdipDeleteGraphics(graphics);
905
906     ReleaseDC(hwnd, hdc);
907 }
908
909 static void test_GdipDrawCurve2I(void)
910 {
911     GpStatus status;
912     GpGraphics *graphics = NULL;
913     GpPen *pen = NULL;
914     HDC hdc = GetDC( hwnd );
915     GpPoint points[3];
916
917     points[0].X = 0;
918     points[0].Y = 0;
919
920     points[1].X = 40;
921     points[1].Y = 20;
922
923     points[2].X = 10;
924     points[2].Y = 40;
925
926     /* make a graphics object and pen object */
927     ok(hdc != NULL, "Expected HDC to be initialized\n");
928
929     status = GdipCreateFromHDC(hdc, &graphics);
930     expect(Ok, status);
931     ok(graphics != NULL, "Expected graphics to be initialized\n");
932
933     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
934     expect(Ok, status);
935     ok(pen != NULL, "Expected pen to be initialized\n");
936
937     /* InvalidParameter cases: null graphics, null pen */
938     status = GdipDrawCurve2I(NULL, NULL, points, 3, 1);
939     expect(InvalidParameter, status);
940
941     status = GdipDrawCurve2I(graphics, NULL, points, 3, 1);
942     expect(InvalidParameter, status);
943
944     status = GdipDrawCurve2I(NULL, pen, points, 3, 1);
945     expect(InvalidParameter, status);
946
947     /* InvalidParameter cases: invalid count */
948     status = GdipDrawCurve2I(graphics, pen, points, -1, 1);
949     expect(OutOfMemory, status);
950
951     status = GdipDrawCurve2I(graphics, pen, points, 0, 1);
952     expect(InvalidParameter, status);
953
954     status = GdipDrawCurve2I(graphics, pen, points, 1, 1);
955     expect(InvalidParameter, status);
956
957     /* Valid test cases */
958     status = GdipDrawCurve2I(graphics, pen, points, 2, 1);
959     expect(Ok, status);
960
961     status = GdipDrawCurve2I(graphics, pen, points, 3, 2);
962     expect(Ok, status);
963
964     status = GdipDrawCurve2I(graphics, pen, points, 3, -2);
965     expect(Ok, status);
966
967     status = GdipDrawCurve2I(graphics, pen, points, 3, 0);
968     expect(Ok, status);
969
970     GdipDeletePen(pen);
971     GdipDeleteGraphics(graphics);
972
973     ReleaseDC(hwnd, hdc);
974 }
975
976 static void test_GdipDrawCurve(void)
977 {
978     GpStatus status;
979     GpGraphics *graphics = NULL;
980     GpPen *pen = NULL;
981     HDC hdc = GetDC( hwnd );
982     GpPointF points[3];
983
984     points[0].X = 0;
985     points[0].Y = 0;
986
987     points[1].X = 40;
988     points[1].Y = 20;
989
990     points[2].X = 10;
991     points[2].Y = 40;
992
993     /* make a graphics object and pen object */
994     ok(hdc != NULL, "Expected HDC to be initialized\n");
995
996     status = GdipCreateFromHDC(hdc, &graphics);
997     expect(Ok, status);
998     ok(graphics != NULL, "Expected graphics to be initialized\n");
999
1000     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1001     expect(Ok, status);
1002     ok(pen != NULL, "Expected pen to be initialized\n");
1003
1004     /* InvalidParameter cases: null graphics, null pen */
1005     status = GdipDrawCurve(NULL, NULL, points, 3);
1006     expect(InvalidParameter, status);
1007
1008     status = GdipDrawCurve(graphics, NULL, points, 3);
1009     expect(InvalidParameter, status);
1010
1011     status = GdipDrawCurve(NULL, pen, points, 3);
1012     expect(InvalidParameter, status);
1013
1014     /* InvalidParameter cases: invalid count */
1015     status = GdipDrawCurve(graphics, pen, points, -1);
1016     expect(InvalidParameter, status);
1017
1018     status = GdipDrawCurve(graphics, pen, points, 0);
1019     expect(InvalidParameter, status);
1020
1021     status = GdipDrawCurve(graphics, pen, points, 1);
1022     expect(InvalidParameter, status);
1023
1024     /* Valid test cases */
1025     status = GdipDrawCurve(graphics, pen, points, 2);
1026     expect(Ok, status);
1027
1028     status = GdipDrawCurve(graphics, pen, points, 3);
1029     expect(Ok, status);
1030
1031     GdipDeletePen(pen);
1032     GdipDeleteGraphics(graphics);
1033
1034     ReleaseDC(hwnd, hdc);
1035 }
1036
1037 static void test_GdipDrawCurveI(void)
1038 {
1039     GpStatus status;
1040     GpGraphics *graphics = NULL;
1041     GpPen *pen = NULL;
1042     HDC hdc = GetDC( hwnd );
1043     GpPoint points[3];
1044
1045     points[0].X = 0;
1046     points[0].Y = 0;
1047
1048     points[1].X = 40;
1049     points[1].Y = 20;
1050
1051     points[2].X = 10;
1052     points[2].Y = 40;
1053
1054     /* make a graphics object and pen object */
1055     ok(hdc != NULL, "Expected HDC to be initialized\n");
1056
1057     status = GdipCreateFromHDC(hdc, &graphics);
1058     expect(Ok, status);
1059     ok(graphics != NULL, "Expected graphics to be initialized\n");
1060
1061     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1062     expect(Ok, status);
1063     ok(pen != NULL, "Expected pen to be initialized\n");
1064
1065     /* InvalidParameter cases: null graphics, null pen */
1066     status = GdipDrawCurveI(NULL, NULL, points, 3);
1067     expect(InvalidParameter, status);
1068
1069     status = GdipDrawCurveI(graphics, NULL, points, 3);
1070     expect(InvalidParameter, status);
1071
1072     status = GdipDrawCurveI(NULL, pen, points, 3);
1073     expect(InvalidParameter, status);
1074
1075     /* InvalidParameter cases: invalid count */
1076     status = GdipDrawCurveI(graphics, pen, points, -1);
1077     expect(OutOfMemory, status);
1078
1079     status = GdipDrawCurveI(graphics, pen, points, 0);
1080     expect(InvalidParameter, status);
1081
1082     status = GdipDrawCurveI(graphics, pen, points, 1);
1083     expect(InvalidParameter, status);
1084
1085     /* Valid test cases */
1086     status = GdipDrawCurveI(graphics, pen, points, 2);
1087     expect(Ok, status);
1088
1089     status = GdipDrawCurveI(graphics, pen, points, 3);
1090     expect(Ok, status);
1091
1092     GdipDeletePen(pen);
1093     GdipDeleteGraphics(graphics);
1094
1095     ReleaseDC(hwnd, hdc);
1096 }
1097
1098 static void test_GdipDrawLineI(void)
1099 {
1100     GpStatus status;
1101     GpGraphics *graphics = NULL;
1102     GpPen *pen = NULL;
1103     HDC hdc = GetDC( hwnd );
1104
1105     /* make a graphics object and pen object */
1106     ok(hdc != NULL, "Expected HDC to be initialized\n");
1107
1108     status = GdipCreateFromHDC(hdc, &graphics);
1109     expect(Ok, status);
1110     ok(graphics != NULL, "Expected graphics to be initialized\n");
1111
1112     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1113     expect(Ok, status);
1114     ok(pen != NULL, "Expected pen to be initialized\n");
1115
1116     /* InvalidParameter cases: null graphics, null pen */
1117     status = GdipDrawLineI(NULL, NULL, 0, 0, 0, 0);
1118     expect(InvalidParameter, status);
1119
1120     status = GdipDrawLineI(graphics, NULL, 0, 0, 0, 0);
1121     expect(InvalidParameter, status);
1122
1123     status = GdipDrawLineI(NULL, pen, 0, 0, 0, 0);
1124     expect(InvalidParameter, status);
1125
1126     /* successful case */
1127     status = GdipDrawLineI(graphics, pen, 0, 0, 0, 0);
1128     expect(Ok, status);
1129
1130     GdipDeletePen(pen);
1131     GdipDeleteGraphics(graphics);
1132
1133     ReleaseDC(hwnd, hdc);
1134 }
1135
1136 static void test_GdipDrawImagePointsRect(void)
1137 {
1138     GpStatus status;
1139     GpGraphics *graphics = NULL;
1140     GpPointF ptf[4];
1141     GpBitmap *bm = NULL;
1142     BYTE rbmi[sizeof(BITMAPINFOHEADER)];
1143     BYTE buff[400];
1144     BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
1145     HDC hdc = GetDC( hwnd );
1146     if (!hdc)
1147         return;
1148
1149     memset(rbmi, 0, sizeof(rbmi));
1150     bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1151     bmi->bmiHeader.biWidth = 10;
1152     bmi->bmiHeader.biHeight = 10;
1153     bmi->bmiHeader.biPlanes = 1;
1154     bmi->bmiHeader.biBitCount = 32;
1155     bmi->bmiHeader.biCompression = BI_RGB;
1156     status = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
1157     expect(Ok, status);
1158     ok(NULL != bm, "Expected bitmap to be initialized\n");
1159     status = GdipCreateFromHDC(hdc, &graphics);
1160     expect(Ok, status);
1161     ptf[0].X = 0;
1162     ptf[0].Y = 0;
1163     ptf[1].X = 10;
1164     ptf[1].Y = 0;
1165     ptf[2].X = 0;
1166     ptf[2].Y = 10;
1167     ptf[3].X = 10;
1168     ptf[3].Y = 10;
1169     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 4, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1170     expect(NotImplemented, status);
1171     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 2, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1172     expect(InvalidParameter, status);
1173     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1174     expect(Ok, status);
1175     status = GdipDrawImagePointsRect(graphics, NULL, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1176     expect(InvalidParameter, status);
1177     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, NULL, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1178     expect(InvalidParameter, status);
1179     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 0, 0, UnitPixel, NULL, NULL, NULL);
1180     expect(Ok, status);
1181     memset(ptf, 0, sizeof(ptf));
1182     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1183     expect(Ok, status);
1184
1185     GdipDisposeImage((GpImage*)bm);
1186     GdipDeleteGraphics(graphics);
1187     ReleaseDC(hwnd, hdc);
1188 }
1189
1190 static void test_GdipDrawLinesI(void)
1191 {
1192     GpStatus status;
1193     GpGraphics *graphics = NULL;
1194     GpPen *pen = NULL;
1195     GpPoint *ptf = NULL;
1196     HDC hdc = GetDC( hwnd );
1197
1198     /* make a graphics object and pen object */
1199     ok(hdc != NULL, "Expected HDC to be initialized\n");
1200
1201     status = GdipCreateFromHDC(hdc, &graphics);
1202     expect(Ok, status);
1203     ok(graphics != NULL, "Expected graphics to be initialized\n");
1204
1205     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1206     expect(Ok, status);
1207     ok(pen != NULL, "Expected pen to be initialized\n");
1208
1209     /* make some arbitrary valid points*/
1210     ptf = GdipAlloc(2 * sizeof(GpPointF));
1211
1212     ptf[0].X = 1;
1213     ptf[0].Y = 1;
1214
1215     ptf[1].X = 2;
1216     ptf[1].Y = 2;
1217
1218     /* InvalidParameter cases: null graphics, null pen, null points, count < 2*/
1219     status = GdipDrawLinesI(NULL, NULL, NULL, 0);
1220     expect(InvalidParameter, status);
1221
1222     status = GdipDrawLinesI(graphics, pen, ptf, 0);
1223     expect(InvalidParameter, status);
1224
1225     status = GdipDrawLinesI(graphics, NULL, ptf, 2);
1226     expect(InvalidParameter, status);
1227
1228     status = GdipDrawLinesI(NULL, pen, ptf, 2);
1229     expect(InvalidParameter, status);
1230
1231     /* successful case */
1232     status = GdipDrawLinesI(graphics, pen, ptf, 2);
1233     expect(Ok, status);
1234
1235     GdipFree(ptf);
1236     GdipDeletePen(pen);
1237     GdipDeleteGraphics(graphics);
1238
1239     ReleaseDC(hwnd, hdc);
1240 }
1241
1242 static void test_GdipFillClosedCurve(void)
1243 {
1244     GpStatus status;
1245     GpGraphics *graphics = NULL;
1246     GpSolidFill *brush = NULL;
1247     HDC hdc = GetDC( hwnd );
1248     GpPointF points[3];
1249
1250     points[0].X = 0;
1251     points[0].Y = 0;
1252
1253     points[1].X = 40;
1254     points[1].Y = 20;
1255
1256     points[2].X = 10;
1257     points[2].Y = 40;
1258
1259     /* make a graphics object and brush object */
1260     ok(hdc != NULL, "Expected HDC to be initialized\n");
1261
1262     status = GdipCreateFromHDC(hdc, &graphics);
1263     expect(Ok, status);
1264     ok(graphics != NULL, "Expected graphics to be initialized\n");
1265
1266     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1267
1268     /* InvalidParameter cases: null graphics, null brush, null points */
1269     status = GdipFillClosedCurve(NULL, NULL, NULL, 3);
1270     expect(InvalidParameter, status);
1271
1272     status = GdipFillClosedCurve(graphics, NULL, NULL, 3);
1273     expect(InvalidParameter, status);
1274
1275     status = GdipFillClosedCurve(NULL, (GpBrush*)brush, NULL, 3);
1276     expect(InvalidParameter, status);
1277
1278     status = GdipFillClosedCurve(NULL, NULL, points, 3);
1279     expect(InvalidParameter, status);
1280
1281     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, NULL, 3);
1282     expect(InvalidParameter, status);
1283
1284     status = GdipFillClosedCurve(graphics, NULL, points, 3);
1285     expect(InvalidParameter, status);
1286
1287     status = GdipFillClosedCurve(NULL, (GpBrush*)brush, points, 3);
1288     expect(InvalidParameter, status);
1289
1290     /* InvalidParameter cases: invalid count */
1291     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, -1);
1292     expect(InvalidParameter, status);
1293
1294     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 0);
1295     expect(InvalidParameter, status);
1296
1297     /* Valid test cases */
1298     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 1);
1299     expect(Ok, status);
1300
1301     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 2);
1302     expect(Ok, status);
1303
1304     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 3);
1305     expect(Ok, status);
1306
1307     GdipDeleteGraphics(graphics);
1308     GdipDeleteBrush((GpBrush*)brush);
1309
1310     ReleaseDC(hwnd, hdc);
1311 }
1312
1313 static void test_GdipFillClosedCurveI(void)
1314 {
1315     GpStatus status;
1316     GpGraphics *graphics = NULL;
1317     GpSolidFill *brush = NULL;
1318     HDC hdc = GetDC( hwnd );
1319     GpPoint points[3];
1320
1321     points[0].X = 0;
1322     points[0].Y = 0;
1323
1324     points[1].X = 40;
1325     points[1].Y = 20;
1326
1327     points[2].X = 10;
1328     points[2].Y = 40;
1329
1330     /* make a graphics object and brush object */
1331     ok(hdc != NULL, "Expected HDC to be initialized\n");
1332
1333     status = GdipCreateFromHDC(hdc, &graphics);
1334     expect(Ok, status);
1335     ok(graphics != NULL, "Expected graphics to be initialized\n");
1336
1337     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1338
1339     /* InvalidParameter cases: null graphics, null brush */
1340     /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
1341              when points == NULL, so don't test this condition */
1342     status = GdipFillClosedCurveI(NULL, NULL, points, 3);
1343     expect(InvalidParameter, status);
1344
1345     status = GdipFillClosedCurveI(graphics, NULL, points, 3);
1346     expect(InvalidParameter, status);
1347
1348     status = GdipFillClosedCurveI(NULL, (GpBrush*)brush, points, 3);
1349     expect(InvalidParameter, status);
1350
1351     /* InvalidParameter cases: invalid count */
1352     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 0);
1353     expect(InvalidParameter, status);
1354
1355     /* OutOfMemory cases: large (unsigned) int */
1356     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, -1);
1357     expect(OutOfMemory, status);
1358
1359     /* Valid test cases */
1360     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 1);
1361     expect(Ok, status);
1362
1363     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 2);
1364     expect(Ok, status);
1365
1366     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 3);
1367     expect(Ok, status);
1368
1369     GdipDeleteGraphics(graphics);
1370     GdipDeleteBrush((GpBrush*)brush);
1371
1372     ReleaseDC(hwnd, hdc);
1373 }
1374
1375 static void test_Get_Release_DC(void)
1376 {
1377     GpStatus status;
1378     GpGraphics *graphics = NULL;
1379     GpPen *pen;
1380     GpSolidFill *brush;
1381     GpPath *path;
1382     HDC hdc = GetDC( hwnd );
1383     HDC retdc;
1384     REAL r;
1385     CompositingQuality quality;
1386     CompositingMode compmode;
1387     InterpolationMode intmode;
1388     GpMatrix *m;
1389     GpRegion *region;
1390     GpUnit unit;
1391     PixelOffsetMode offsetmode;
1392     SmoothingMode smoothmode;
1393     TextRenderingHint texthint;
1394     GpPointF ptf[5];
1395     GpPoint  pt[5];
1396     GpRectF  rectf[2];
1397     GpRect   rect[2];
1398     GpRegion *clip;
1399     INT i;
1400     BOOL res;
1401     ARGB color = 0x00000000;
1402     HRGN hrgn = CreateRectRgn(0, 0, 10, 10);
1403
1404     pt[0].X = 10;
1405     pt[0].Y = 10;
1406     pt[1].X = 20;
1407     pt[1].Y = 15;
1408     pt[2].X = 40;
1409     pt[2].Y = 80;
1410     pt[3].X = -20;
1411     pt[3].Y = 20;
1412     pt[4].X = 50;
1413     pt[4].Y = 110;
1414
1415     for(i = 0; i < 5;i++){
1416         ptf[i].X = (REAL)pt[i].X;
1417         ptf[i].Y = (REAL)pt[i].Y;
1418     }
1419
1420     rect[0].X = 0;
1421     rect[0].Y = 0;
1422     rect[0].Width  = 50;
1423     rect[0].Height = 70;
1424     rect[1].X = 0;
1425     rect[1].Y = 0;
1426     rect[1].Width  = 10;
1427     rect[1].Height = 20;
1428
1429     for(i = 0; i < 2;i++){
1430         rectf[i].X = (REAL)rect[i].X;
1431         rectf[i].Y = (REAL)rect[i].Y;
1432         rectf[i].Height = (REAL)rect[i].Height;
1433         rectf[i].Width  = (REAL)rect[i].Width;
1434     }
1435
1436     status = GdipCreateMatrix(&m);
1437     expect(Ok, status);
1438     GdipCreateRegion(&region);
1439     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1440     GdipCreatePath(FillModeAlternate, &path);
1441     GdipCreateRegion(&clip);
1442
1443     status = GdipCreateFromHDC(hdc, &graphics);
1444     expect(Ok, status);
1445     ok(graphics != NULL, "Expected graphics to be initialized\n");
1446     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1447     expect(Ok, status);
1448
1449     /* NULL arguments */
1450     status = GdipGetDC(NULL, NULL);
1451     expect(InvalidParameter, status);
1452     status = GdipGetDC(graphics, NULL);
1453     expect(InvalidParameter, status);
1454     status = GdipGetDC(NULL, &retdc);
1455     expect(InvalidParameter, status);
1456
1457     status = GdipReleaseDC(NULL, NULL);
1458     expect(InvalidParameter, status);
1459     status = GdipReleaseDC(graphics, NULL);
1460     expect(InvalidParameter, status);
1461     status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
1462     expect(InvalidParameter, status);
1463
1464     /* Release without Get */
1465     status = GdipReleaseDC(graphics, hdc);
1466     expect(InvalidParameter, status);
1467
1468     retdc = NULL;
1469     status = GdipGetDC(graphics, &retdc);
1470     expect(Ok, status);
1471     ok(retdc == hdc, "Invalid HDC returned\n");
1472     /* call it once more */
1473     status = GdipGetDC(graphics, &retdc);
1474     expect(ObjectBusy, status);
1475
1476     /* try all Graphics calls here */
1477     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
1478     expect(ObjectBusy, status);
1479     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
1480     expect(ObjectBusy, status);
1481     status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
1482     expect(ObjectBusy, status);
1483     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
1484     expect(ObjectBusy, status);
1485     status = GdipDrawBeziers(graphics, pen, ptf, 5);
1486     expect(ObjectBusy, status);
1487     status = GdipDrawBeziersI(graphics, pen, pt, 5);
1488     expect(ObjectBusy, status);
1489     status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
1490     expect(ObjectBusy, status);
1491     status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
1492     expect(ObjectBusy, status);
1493     status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
1494     expect(ObjectBusy, status);
1495     status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
1496     expect(ObjectBusy, status);
1497     status = GdipDrawCurve(graphics, pen, ptf, 5);
1498     expect(ObjectBusy, status);
1499     status = GdipDrawCurveI(graphics, pen, pt, 5);
1500     expect(ObjectBusy, status);
1501     status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
1502     expect(ObjectBusy, status);
1503     status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
1504     expect(ObjectBusy, status);
1505     status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
1506     expect(ObjectBusy, status);
1507     status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
1508     expect(ObjectBusy, status);
1509     /* GdipDrawImage/GdipDrawImageI */
1510     /* GdipDrawImagePointsRect/GdipDrawImagePointsRectI */
1511     /* GdipDrawImageRectRect/GdipDrawImageRectRectI */
1512     /* GdipDrawImageRect/GdipDrawImageRectI */
1513     status = GdipDrawLine(graphics, pen, 0.0, 0.0, 100.0, 200.0);
1514     expect(ObjectBusy, status);
1515     status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
1516     expect(ObjectBusy, status);
1517     status = GdipDrawLines(graphics, pen, ptf, 5);
1518     expect(ObjectBusy, status);
1519     status = GdipDrawLinesI(graphics, pen, pt, 5);
1520     expect(ObjectBusy, status);
1521     status = GdipDrawPath(graphics, pen, path);
1522     expect(ObjectBusy, status);
1523     status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1524     expect(ObjectBusy, status);
1525     status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
1526     expect(ObjectBusy, status);
1527     status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
1528     expect(ObjectBusy, status);
1529     status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
1530     expect(ObjectBusy, status);
1531     status = GdipDrawRectangles(graphics, pen, rectf, 2);
1532     expect(ObjectBusy, status);
1533     status = GdipDrawRectanglesI(graphics, pen, rect, 2);
1534     expect(ObjectBusy, status);
1535     /* GdipDrawString */
1536     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
1537     expect(ObjectBusy, status);
1538     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
1539     expect(ObjectBusy, status);
1540     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, ptf, 5);
1541     expect(ObjectBusy, status);
1542     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, pt, 5);
1543     expect(ObjectBusy, status);
1544     status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1545     expect(ObjectBusy, status);
1546     status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1547     expect(ObjectBusy, status);
1548     status = GdipFillPath(graphics, (GpBrush*)brush, path);
1549     expect(ObjectBusy, status);
1550     status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
1551     expect(ObjectBusy, status);
1552     status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
1553     expect(ObjectBusy, status);
1554     status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
1555     expect(ObjectBusy, status);
1556     status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
1557     expect(ObjectBusy, status);
1558     status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
1559     expect(ObjectBusy, status);
1560     status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
1561     expect(ObjectBusy, status);
1562     status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1563     expect(ObjectBusy, status);
1564     status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1565     expect(ObjectBusy, status);
1566     status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
1567     expect(ObjectBusy, status);
1568     status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
1569     expect(ObjectBusy, status);
1570     status = GdipFillRegion(graphics, (GpBrush*)brush, region);
1571     expect(ObjectBusy, status);
1572     status = GdipFlush(graphics, FlushIntentionFlush);
1573     expect(ObjectBusy, status);
1574     status = GdipGetClipBounds(graphics, rectf);
1575     expect(ObjectBusy, status);
1576     status = GdipGetClipBoundsI(graphics, rect);
1577     expect(ObjectBusy, status);
1578     status = GdipGetCompositingMode(graphics, &compmode);
1579     expect(ObjectBusy, status);
1580     status = GdipGetCompositingQuality(graphics, &quality);
1581     expect(ObjectBusy, status);
1582     status = GdipGetInterpolationMode(graphics, &intmode);
1583     expect(ObjectBusy, status);
1584     status = GdipGetNearestColor(graphics, &color);
1585     expect(ObjectBusy, status);
1586     status = GdipGetPageScale(graphics, &r);
1587     expect(ObjectBusy, status);
1588     status = GdipGetPageUnit(graphics, &unit);
1589     expect(ObjectBusy, status);
1590     status = GdipGetPixelOffsetMode(graphics, &offsetmode);
1591     expect(ObjectBusy, status);
1592     status = GdipGetSmoothingMode(graphics, &smoothmode);
1593     expect(ObjectBusy, status);
1594     status = GdipGetTextRenderingHint(graphics, &texthint);
1595     expect(ObjectBusy, status);
1596     status = GdipGetWorldTransform(graphics, m);
1597     expect(ObjectBusy, status);
1598     status = GdipGraphicsClear(graphics, 0xdeadbeef);
1599     expect(ObjectBusy, status);
1600     status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
1601     expect(ObjectBusy, status);
1602     status = GdipIsVisiblePointI(graphics, 0, 0, &res);
1603     expect(ObjectBusy, status);
1604     /* GdipMeasureCharacterRanges */
1605     /* GdipMeasureString */
1606     status = GdipResetClip(graphics);
1607     expect(ObjectBusy, status);
1608     status = GdipResetWorldTransform(graphics);
1609     expect(ObjectBusy, status);
1610     /* GdipRestoreGraphics */
1611     status = GdipRotateWorldTransform(graphics, 15.0, MatrixOrderPrepend);
1612     expect(ObjectBusy, status);
1613     /*  GdipSaveGraphics */
1614     status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
1615     expect(ObjectBusy, status);
1616     status = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
1617     expect(ObjectBusy, status);
1618     status = GdipSetCompositingQuality(graphics, CompositingQualityDefault);
1619     expect(ObjectBusy, status);
1620     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
1621     expect(ObjectBusy, status);
1622     status = GdipSetPageScale(graphics, 1.0);
1623     expect(ObjectBusy, status);
1624     status = GdipSetPageUnit(graphics, UnitWorld);
1625     expect(ObjectBusy, status);
1626     status = GdipSetPixelOffsetMode(graphics, PixelOffsetModeDefault);
1627     expect(ObjectBusy, status);
1628     status = GdipSetSmoothingMode(graphics, SmoothingModeDefault);
1629     expect(ObjectBusy, status);
1630     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
1631     expect(ObjectBusy, status);
1632     status = GdipSetWorldTransform(graphics, m);
1633     expect(ObjectBusy, status);
1634     status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
1635     expect(ObjectBusy, status);
1636     status = GdipSetClipHrgn(graphics, hrgn, CombineModeReplace);
1637     expect(ObjectBusy, status);
1638     status = GdipSetClipPath(graphics, path, CombineModeReplace);
1639     expect(ObjectBusy, status);
1640     status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
1641     expect(ObjectBusy, status);
1642     status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
1643     expect(ObjectBusy, status);
1644     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1645     expect(ObjectBusy, status);
1646     status = GdipTranslateClip(graphics, 0.0, 0.0);
1647     expect(ObjectBusy, status);
1648     status = GdipTranslateClipI(graphics, 0, 0);
1649     expect(ObjectBusy, status);
1650     status = GdipDrawPolygon(graphics, pen, ptf, 5);
1651     expect(ObjectBusy, status);
1652     status = GdipDrawPolygonI(graphics, pen, pt, 5);
1653     expect(ObjectBusy, status);
1654     status = GdipGetDpiX(graphics, &r);
1655     expect(ObjectBusy, status);
1656     status = GdipGetDpiY(graphics, &r);
1657     expect(ObjectBusy, status);
1658     status = GdipMultiplyWorldTransform(graphics, m, MatrixOrderPrepend);
1659     expect(ObjectBusy, status);
1660     status = GdipGetClip(graphics, region);
1661     expect(ObjectBusy, status);
1662     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 5);
1663     expect(ObjectBusy, status);
1664
1665     /* try to delete before release */
1666     status = GdipDeleteGraphics(graphics);
1667     expect(ObjectBusy, status);
1668
1669     status = GdipReleaseDC(graphics, retdc);
1670     expect(Ok, status);
1671
1672     GdipDeletePen(pen);
1673     GdipDeleteGraphics(graphics);
1674
1675     GdipDeleteRegion(clip);
1676     GdipDeletePath(path);
1677     GdipDeleteBrush((GpBrush*)brush);
1678     GdipDeleteRegion(region);
1679     GdipDeleteMatrix(m);
1680     DeleteObject(hrgn);
1681
1682     ReleaseDC(hwnd, hdc);
1683 }
1684
1685 static void test_transformpoints(void)
1686 {
1687     GpStatus status;
1688     GpGraphics *graphics = NULL;
1689     HDC hdc = GetDC( hwnd );
1690     GpPointF ptf[2];
1691     GpPoint pt[2];
1692
1693     status = GdipCreateFromHDC(hdc, &graphics);
1694     expect(Ok, status);
1695
1696     /* NULL arguments */
1697     status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1698     expect(InvalidParameter, status);
1699     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1700     expect(InvalidParameter, status);
1701     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 0);
1702     expect(InvalidParameter, status);
1703     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1);
1704     expect(InvalidParameter, status);
1705
1706     ptf[0].X = 1.0;
1707     ptf[0].Y = 0.0;
1708     ptf[1].X = 0.0;
1709     ptf[1].Y = 1.0;
1710     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1711     expect(Ok, status);
1712     expectf(1.0, ptf[0].X);
1713     expectf(0.0, ptf[0].Y);
1714     expectf(0.0, ptf[1].X);
1715     expectf(1.0, ptf[1].Y);
1716
1717     status = GdipTranslateWorldTransform(graphics, 5.0, 5.0, MatrixOrderAppend);
1718     expect(Ok, status);
1719     status = GdipSetPageUnit(graphics, UnitPixel);
1720     expect(Ok, status);
1721     status = GdipSetPageScale(graphics, 3.0);
1722     expect(Ok, status);
1723
1724     ptf[0].X = 1.0;
1725     ptf[0].Y = 0.0;
1726     ptf[1].X = 0.0;
1727     ptf[1].Y = 1.0;
1728     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1729     expect(Ok, status);
1730     expectf(18.0, ptf[0].X);
1731     expectf(15.0, ptf[0].Y);
1732     expectf(15.0, ptf[1].X);
1733     expectf(18.0, ptf[1].Y);
1734
1735     ptf[0].X = 1.0;
1736     ptf[0].Y = 0.0;
1737     ptf[1].X = 0.0;
1738     ptf[1].Y = 1.0;
1739     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 2);
1740     expect(Ok, status);
1741     expectf(6.0, ptf[0].X);
1742     expectf(5.0, ptf[0].Y);
1743     expectf(5.0, ptf[1].X);
1744     expectf(6.0, ptf[1].Y);
1745
1746     ptf[0].X = 1.0;
1747     ptf[0].Y = 0.0;
1748     ptf[1].X = 0.0;
1749     ptf[1].Y = 1.0;
1750     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpacePage, ptf, 2);
1751     expect(Ok, status);
1752     expectf(3.0, ptf[0].X);
1753     expectf(0.0, ptf[0].Y);
1754     expectf(0.0, ptf[1].X);
1755     expectf(3.0, ptf[1].Y);
1756
1757     ptf[0].X = 18.0;
1758     ptf[0].Y = 15.0;
1759     ptf[1].X = 15.0;
1760     ptf[1].Y = 18.0;
1761     status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
1762     expect(Ok, status);
1763     expectf(1.0, ptf[0].X);
1764     expectf(0.0, ptf[0].Y);
1765     expectf(0.0, ptf[1].X);
1766     expectf(1.0, ptf[1].Y);
1767
1768     ptf[0].X = 6.0;
1769     ptf[0].Y = 5.0;
1770     ptf[1].X = 5.0;
1771     ptf[1].Y = 6.0;
1772     status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpacePage, ptf, 2);
1773     expect(Ok, status);
1774     expectf(1.0, ptf[0].X);
1775     expectf(0.0, ptf[0].Y);
1776     expectf(0.0, ptf[1].X);
1777     expectf(1.0, ptf[1].Y);
1778
1779     ptf[0].X = 3.0;
1780     ptf[0].Y = 0.0;
1781     ptf[1].X = 0.0;
1782     ptf[1].Y = 3.0;
1783     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceDevice, ptf, 2);
1784     expect(Ok, status);
1785     expectf(1.0, ptf[0].X);
1786     expectf(0.0, ptf[0].Y);
1787     expectf(0.0, ptf[1].X);
1788     expectf(1.0, ptf[1].Y);
1789
1790     pt[0].X = 1;
1791     pt[0].Y = 0;
1792     pt[1].X = 0;
1793     pt[1].Y = 1;
1794     status = GdipTransformPointsI(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 2);
1795     expect(Ok, status);
1796     expect(18, pt[0].X);
1797     expect(15, pt[0].Y);
1798     expect(15, pt[1].X);
1799     expect(18, pt[1].Y);
1800
1801     GdipDeleteGraphics(graphics);
1802     ReleaseDC(hwnd, hdc);
1803 }
1804
1805 static void test_get_set_clip(void)
1806 {
1807     GpStatus status;
1808     GpGraphics *graphics = NULL;
1809     HDC hdc = GetDC( hwnd );
1810     GpRegion *clip;
1811     GpRectF rect;
1812     BOOL res;
1813
1814     status = GdipCreateFromHDC(hdc, &graphics);
1815     expect(Ok, status);
1816
1817     rect.X = rect.Y = 0.0;
1818     rect.Height = rect.Width = 100.0;
1819
1820     status = GdipCreateRegionRect(&rect, &clip);
1821     expect(Ok, status);
1822
1823     /* NULL arguments */
1824     status = GdipGetClip(NULL, NULL);
1825     expect(InvalidParameter, status);
1826     status = GdipGetClip(graphics, NULL);
1827     expect(InvalidParameter, status);
1828     status = GdipGetClip(NULL, clip);
1829     expect(InvalidParameter, status);
1830
1831     status = GdipSetClipRegion(NULL, NULL, CombineModeReplace);
1832     expect(InvalidParameter, status);
1833     status = GdipSetClipRegion(graphics, NULL, CombineModeReplace);
1834     expect(InvalidParameter, status);
1835
1836     status = GdipSetClipPath(NULL, NULL, CombineModeReplace);
1837     expect(InvalidParameter, status);
1838     status = GdipSetClipPath(graphics, NULL, CombineModeReplace);
1839     expect(InvalidParameter, status);
1840
1841     res = FALSE;
1842     status = GdipGetClip(graphics, clip);
1843     expect(Ok, status);
1844     status = GdipIsInfiniteRegion(clip, graphics, &res);
1845     expect(Ok, status);
1846     expect(TRUE, res);
1847
1848     /* remains infinite after reset */
1849     res = FALSE;
1850     status = GdipResetClip(graphics);
1851     expect(Ok, status);
1852     status = GdipGetClip(graphics, clip);
1853     expect(Ok, status);
1854     status = GdipIsInfiniteRegion(clip, graphics, &res);
1855     expect(Ok, status);
1856     expect(TRUE, res);
1857
1858     /* set to empty and then reset to infinite */
1859     status = GdipSetEmpty(clip);
1860     expect(Ok, status);
1861     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1862     expect(Ok, status);
1863
1864     status = GdipGetClip(graphics, clip);
1865     expect(Ok, status);
1866     res = FALSE;
1867     status = GdipIsEmptyRegion(clip, graphics, &res);
1868     expect(Ok, status);
1869     expect(TRUE, res);
1870     status = GdipResetClip(graphics);
1871     expect(Ok, status);
1872     status = GdipGetClip(graphics, clip);
1873     expect(Ok, status);
1874     res = FALSE;
1875     status = GdipIsInfiniteRegion(clip, graphics, &res);
1876     expect(Ok, status);
1877     expect(TRUE, res);
1878
1879     GdipDeleteRegion(clip);
1880
1881     GdipDeleteGraphics(graphics);
1882     ReleaseDC(hwnd, hdc);
1883 }
1884
1885 static void test_isempty(void)
1886 {
1887     GpStatus status;
1888     GpGraphics *graphics = NULL;
1889     HDC hdc = GetDC( hwnd );
1890     GpRegion *clip;
1891     BOOL res;
1892
1893     status = GdipCreateFromHDC(hdc, &graphics);
1894     expect(Ok, status);
1895
1896     status = GdipCreateRegion(&clip);
1897     expect(Ok, status);
1898
1899     /* NULL */
1900     status = GdipIsClipEmpty(NULL, NULL);
1901     expect(InvalidParameter, status);
1902     status = GdipIsClipEmpty(graphics, NULL);
1903     expect(InvalidParameter, status);
1904     status = GdipIsClipEmpty(NULL, &res);
1905     expect(InvalidParameter, status);
1906
1907     /* default is infinite */
1908     res = TRUE;
1909     status = GdipIsClipEmpty(graphics, &res);
1910     expect(Ok, status);
1911     expect(FALSE, res);
1912
1913     GdipDeleteRegion(clip);
1914
1915     GdipDeleteGraphics(graphics);
1916     ReleaseDC(hwnd, hdc);
1917 }
1918
1919 static void test_clear(void)
1920 {
1921     GpStatus status;
1922
1923     status = GdipGraphicsClear(NULL, 0xdeadbeef);
1924     expect(InvalidParameter, status);
1925 }
1926
1927 static void test_textcontrast(void)
1928 {
1929     GpStatus status;
1930     HDC hdc = GetDC( hwnd );
1931     GpGraphics *graphics;
1932     UINT contrast;
1933
1934     status = GdipGetTextContrast(NULL, NULL);
1935     expect(InvalidParameter, status);
1936
1937     status = GdipCreateFromHDC(hdc, &graphics);
1938     expect(Ok, status);
1939
1940     status = GdipGetTextContrast(graphics, NULL);
1941     expect(InvalidParameter, status);
1942     status = GdipGetTextContrast(graphics, &contrast);
1943     expect(Ok, status);
1944     expect(4, contrast);
1945
1946     GdipDeleteGraphics(graphics);
1947     ReleaseDC(hwnd, hdc);
1948 }
1949
1950 static void test_GdipDrawString(void)
1951 {
1952     GpStatus status;
1953     GpGraphics *graphics = NULL;
1954     GpFont *fnt = NULL;
1955     RectF  rect;
1956     GpStringFormat *format;
1957     GpBrush *brush;
1958     LOGFONTA logfont;
1959     HDC hdc = GetDC( hwnd );
1960     static const WCHAR string[] = {'T','e','s','t',0};
1961     static const PointF positions[4] = {{0,0}, {1,1}, {2,2}, {3,3}};
1962     GpMatrix *matrix;
1963
1964     memset(&logfont,0,sizeof(logfont));
1965     strcpy(logfont.lfFaceName,"Arial");
1966     logfont.lfHeight = 12;
1967     logfont.lfCharSet = DEFAULT_CHARSET;
1968
1969     status = GdipCreateFromHDC(hdc, &graphics);
1970     expect(Ok, status);
1971
1972     status = GdipCreateFontFromLogfontA(hdc, &logfont, &fnt);
1973     if (status == FileNotFound)
1974     {
1975         skip("Arial not installed.\n");
1976         return;
1977     }
1978     expect(Ok, status);
1979
1980     status = GdipCreateSolidFill((ARGB)0xdeadbeef, (GpSolidFill**)&brush);
1981     expect(Ok, status);
1982
1983     status = GdipCreateStringFormat(0,0,&format);
1984     expect(Ok, status);
1985
1986     rect.X = 0;
1987     rect.Y = 0;
1988     rect.Width = 0;
1989     rect.Height = 12;
1990
1991     status = GdipDrawString(graphics, string, 4, fnt, &rect, format, brush);
1992     expect(Ok, status);
1993
1994     status = GdipCreateMatrix(&matrix);
1995     expect(Ok, status);
1996
1997     status = GdipDrawDriverString(NULL, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
1998     expect(InvalidParameter, status);
1999
2000     status = GdipDrawDriverString(graphics, NULL, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2001     expect(InvalidParameter, status);
2002
2003     status = GdipDrawDriverString(graphics, string, 4, NULL, brush, positions, DriverStringOptionsCmapLookup, matrix);
2004     expect(InvalidParameter, status);
2005
2006     status = GdipDrawDriverString(graphics, string, 4, fnt, NULL, positions, DriverStringOptionsCmapLookup, matrix);
2007     expect(InvalidParameter, status);
2008
2009     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, NULL, DriverStringOptionsCmapLookup, matrix);
2010     expect(InvalidParameter, status);
2011
2012     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup|0x10, matrix);
2013     expect(Ok, status);
2014
2015     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, NULL);
2016     expect(Ok, status);
2017
2018     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2019     expect(Ok, status);
2020
2021     GdipDeleteMatrix(matrix);
2022     GdipDeleteGraphics(graphics);
2023     GdipDeleteBrush(brush);
2024     GdipDeleteFont(fnt);
2025     GdipDeleteStringFormat(format);
2026
2027     ReleaseDC(hwnd, hdc);
2028 }
2029
2030 static void test_GdipGetVisibleClipBounds_screen(void)
2031 {
2032     GpStatus status;
2033     GpGraphics *graphics = NULL;
2034     HDC hdc = GetDC(0);
2035     GpRectF rectf, exp, clipr;
2036     GpRect recti;
2037
2038     ok(hdc != NULL, "Expected HDC to be initialized\n");
2039
2040     status = GdipCreateFromHDC(hdc, &graphics);
2041     expect(Ok, status);
2042     ok(graphics != NULL, "Expected graphics to be initialized\n");
2043
2044     /* no clipping rect */
2045     exp.X = 0;
2046     exp.Y = 0;
2047     exp.Width = GetDeviceCaps(hdc, HORZRES);
2048     exp.Height = GetDeviceCaps(hdc, VERTRES);
2049
2050     status = GdipGetVisibleClipBounds(graphics, &rectf);
2051     expect(Ok, status);
2052     ok(rectf.X == exp.X &&
2053         rectf.Y == exp.Y &&
2054         rectf.Width == exp.Width &&
2055         rectf.Height == exp.Height,
2056         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2057         "the screen (%0.f, %0.f, %0.f, %0.f)\n",
2058         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2059         exp.X, exp.Y, exp.Width, exp.Height);
2060
2061     /* clipping rect entirely within window */
2062     exp.X = clipr.X = 10;
2063     exp.Y = clipr.Y = 12;
2064     exp.Width = clipr.Width = 14;
2065     exp.Height = clipr.Height = 16;
2066
2067     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2068     expect(Ok, status);
2069
2070     status = GdipGetVisibleClipBounds(graphics, &rectf);
2071     expect(Ok, status);
2072     ok(rectf.X == exp.X &&
2073         rectf.Y == exp.Y &&
2074         rectf.Width == exp.Width &&
2075         rectf.Height == exp.Height,
2076         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2077         "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2078         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2079         exp.X, exp.Y, exp.Width, exp.Height);
2080
2081     /* clipping rect partially outside of screen */
2082     clipr.X = -10;
2083     clipr.Y = -12;
2084     clipr.Width = 20;
2085     clipr.Height = 24;
2086
2087     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2088     expect(Ok, status);
2089
2090     exp.X = 0;
2091     exp.Y = 0;
2092     exp.Width = 10;
2093     exp.Height = 12;
2094
2095     status = GdipGetVisibleClipBounds(graphics, &rectf);
2096     expect(Ok, status);
2097     ok(rectf.X == exp.X &&
2098         rectf.Y == exp.Y &&
2099         rectf.Width == exp.Width &&
2100         rectf.Height == exp.Height,
2101         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2102         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2103         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2104         exp.X, exp.Y, exp.Width, exp.Height);
2105
2106     status = GdipGetVisibleClipBoundsI(graphics, &recti);
2107     expect(Ok, status);
2108     ok(recti.X == exp.X &&
2109         recti.Y == exp.Y &&
2110         recti.Width == exp.Width &&
2111         recti.Height == exp.Height,
2112         "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2113         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2114         recti.X, recti.Y, recti.Width, recti.Height,
2115         exp.X, exp.Y, exp.Width, exp.Height);
2116
2117     GdipDeleteGraphics(graphics);
2118     ReleaseDC(0, hdc);
2119 }
2120
2121 static void test_GdipGetVisibleClipBounds_window(void)
2122 {
2123     GpStatus status;
2124     GpGraphics *graphics = NULL;
2125     GpRectF rectf, window, exp, clipr;
2126     GpRect recti;
2127     HDC hdc;
2128     PAINTSTRUCT ps;
2129     RECT wnd_rect;
2130
2131     /* get client area size */
2132     ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n");
2133     window.X = wnd_rect.left;
2134     window.Y = wnd_rect.top;
2135     window.Width = wnd_rect.right - wnd_rect.left;
2136     window.Height = wnd_rect.bottom - wnd_rect.top;
2137
2138     hdc = BeginPaint(hwnd, &ps);
2139
2140     status = GdipCreateFromHDC(hdc, &graphics);
2141     expect(Ok, status);
2142     ok(graphics != NULL, "Expected graphics to be initialized\n");
2143
2144     status = GdipGetVisibleClipBounds(graphics, &rectf);
2145     expect(Ok, status);
2146     ok(rectf.X == window.X &&
2147         rectf.Y == window.Y &&
2148         rectf.Width == window.Width &&
2149         rectf.Height == window.Height,
2150         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2151         "the window (%0.f, %0.f, %0.f, %0.f)\n",
2152         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2153         window.X, window.Y, window.Width, window.Height);
2154
2155     /* clipping rect entirely within window */
2156     exp.X = clipr.X = 20;
2157     exp.Y = clipr.Y = 8;
2158     exp.Width = clipr.Width = 30;
2159     exp.Height = clipr.Height = 20;
2160
2161     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2162     expect(Ok, status);
2163
2164     status = GdipGetVisibleClipBounds(graphics, &rectf);
2165     expect(Ok, status);
2166     ok(rectf.X == exp.X &&
2167         rectf.Y == exp.Y &&
2168         rectf.Width == exp.Width &&
2169         rectf.Height == exp.Height,
2170         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2171         "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2172         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2173         exp.X, exp.Y, exp.Width, exp.Height);
2174
2175     /* clipping rect partially outside of window */
2176     clipr.X = window.Width - 10;
2177     clipr.Y = window.Height - 15;
2178     clipr.Width = 20;
2179     clipr.Height = 30;
2180
2181     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2182     expect(Ok, status);
2183
2184     exp.X = window.Width - 10;
2185     exp.Y = window.Height - 15;
2186     exp.Width = 10;
2187     exp.Height = 15;
2188
2189     status = GdipGetVisibleClipBounds(graphics, &rectf);
2190     expect(Ok, status);
2191     ok(rectf.X == exp.X &&
2192         rectf.Y == exp.Y &&
2193         rectf.Width == exp.Width &&
2194         rectf.Height == exp.Height,
2195         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2196         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2197         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2198         exp.X, exp.Y, exp.Width, exp.Height);
2199
2200     status = GdipGetVisibleClipBoundsI(graphics, &recti);
2201     expect(Ok, status);
2202     ok(recti.X == exp.X &&
2203         recti.Y == exp.Y &&
2204         recti.Width == exp.Width &&
2205         recti.Height == exp.Height,
2206         "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2207         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2208         recti.X, recti.Y, recti.Width, recti.Height,
2209         exp.X, exp.Y, exp.Width, exp.Height);
2210
2211     GdipDeleteGraphics(graphics);
2212     EndPaint(hwnd, &ps);
2213 }
2214
2215 static void test_GdipGetVisibleClipBounds(void)
2216 {
2217     GpGraphics* graphics = NULL;
2218     GpRectF rectf;
2219     GpRect rect;
2220     HDC hdc = GetDC( hwnd );
2221     GpStatus status;
2222
2223     status = GdipCreateFromHDC(hdc, &graphics);
2224     expect(Ok, status);
2225     ok(graphics != NULL, "Expected graphics to be initialized\n");
2226
2227     /* test null parameters */
2228     status = GdipGetVisibleClipBounds(graphics, NULL);
2229     expect(InvalidParameter, status);
2230
2231     status = GdipGetVisibleClipBounds(NULL, &rectf);
2232     expect(InvalidParameter, status);
2233
2234     status = GdipGetVisibleClipBoundsI(graphics, NULL);
2235     expect(InvalidParameter, status);
2236
2237     status = GdipGetVisibleClipBoundsI(NULL, &rect);
2238     expect(InvalidParameter, status);
2239
2240     GdipDeleteGraphics(graphics);
2241     ReleaseDC(hwnd, hdc);
2242
2243     test_GdipGetVisibleClipBounds_screen();
2244     test_GdipGetVisibleClipBounds_window();
2245 }
2246
2247 static void test_fromMemoryBitmap(void)
2248 {
2249     GpStatus status;
2250     GpGraphics *graphics = NULL;
2251     GpBitmap *bitmap = NULL;
2252     BYTE bits[48] = {0};
2253     HDC hdc=NULL;
2254     COLORREF color;
2255
2256     status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, bits, &bitmap);
2257     expect(Ok, status);
2258
2259     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2260     expect(Ok, status);
2261
2262     status = GdipGraphicsClear(graphics, 0xff686868);
2263     expect(Ok, status);
2264
2265     GdipDeleteGraphics(graphics);
2266
2267     /* drawing writes to the memory provided */
2268     expect(0x68, bits[10]);
2269
2270     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2271     expect(Ok, status);
2272
2273     status = GdipGetDC(graphics, &hdc);
2274     expect(Ok, status);
2275     ok(hdc != NULL, "got NULL hdc\n");
2276
2277     color = GetPixel(hdc, 0, 0);
2278     /* The HDC is write-only, and native fills with a solid color to figure out
2279      * which pixels have changed. */
2280     todo_wine expect(0x0c0b0d, color);
2281
2282     SetPixel(hdc, 0, 0, 0x797979);
2283     SetPixel(hdc, 1, 0, 0x0c0b0d);
2284
2285     status = GdipReleaseDC(graphics, hdc);
2286     expect(Ok, status);
2287
2288     GdipDeleteGraphics(graphics);
2289
2290     expect(0x79, bits[0]);
2291     todo_wine expect(0x68, bits[3]);
2292
2293     GdipDisposeImage((GpImage*)bitmap);
2294
2295     /* We get the same kind of write-only HDC for a "normal" bitmap */
2296     status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, NULL, &bitmap);
2297     expect(Ok, status);
2298
2299     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2300     expect(Ok, status);
2301
2302     status = GdipGetDC(graphics, &hdc);
2303     expect(Ok, status);
2304     ok(hdc != NULL, "got NULL hdc\n");
2305
2306     color = GetPixel(hdc, 0, 0);
2307     todo_wine expect(0x0c0b0d, color);
2308
2309     status = GdipReleaseDC(graphics, hdc);
2310     expect(Ok, status);
2311
2312     GdipDeleteGraphics(graphics);
2313
2314     GdipDisposeImage((GpImage*)bitmap);
2315 }
2316
2317 static void test_GdipIsVisiblePoint(void)
2318 {
2319     GpStatus status;
2320     GpGraphics *graphics = NULL;
2321     HDC hdc = GetDC( hwnd );
2322     REAL x, y;
2323     BOOL val;
2324
2325     ok(hdc != NULL, "Expected HDC to be initialized\n");
2326
2327     status = GdipCreateFromHDC(hdc, &graphics);
2328     expect(Ok, status);
2329     ok(graphics != NULL, "Expected graphics to be initialized\n");
2330
2331     /* null parameters */
2332     status = GdipIsVisiblePoint(NULL, 0, 0, &val);
2333     expect(InvalidParameter, status);
2334
2335     status = GdipIsVisiblePoint(graphics, 0, 0, NULL);
2336     expect(InvalidParameter, status);
2337
2338     status = GdipIsVisiblePointI(NULL, 0, 0, &val);
2339     expect(InvalidParameter, status);
2340
2341     status = GdipIsVisiblePointI(graphics, 0, 0, NULL);
2342     expect(InvalidParameter, status);
2343
2344     x = 0;
2345     y = 0;
2346     status = GdipIsVisiblePoint(graphics, x, y, &val);
2347     expect(Ok, status);
2348     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2349
2350     x = -10;
2351     y = 0;
2352     status = GdipIsVisiblePoint(graphics, x, y, &val);
2353     expect(Ok, status);
2354     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2355
2356     x = 0;
2357     y = -5;
2358     status = GdipIsVisiblePoint(graphics, x, y, &val);
2359     expect(Ok, status);
2360     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2361
2362     x = 1;
2363     y = 1;
2364     status = GdipIsVisiblePoint(graphics, x, y, &val);
2365     expect(Ok, status);
2366     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2367
2368     status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2369     expect(Ok, status);
2370
2371     x = 1;
2372     y = 1;
2373     status = GdipIsVisiblePoint(graphics, x, y, &val);
2374     expect(Ok, status);
2375     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2376
2377     x = 15.5;
2378     y = 40.5;
2379     status = GdipIsVisiblePoint(graphics, x, y, &val);
2380     expect(Ok, status);
2381     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2382
2383     /* translate into the center of the rect */
2384     GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2385
2386     x = 0;
2387     y = 0;
2388     status = GdipIsVisiblePoint(graphics, x, y, &val);
2389     expect(Ok, status);
2390     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2391
2392     x = 25;
2393     y = 40;
2394     status = GdipIsVisiblePoint(graphics, x, y, &val);
2395     expect(Ok, status);
2396     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2397
2398     GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2399
2400     /* corner cases */
2401     x = 9;
2402     y = 19;
2403     status = GdipIsVisiblePoint(graphics, x, y, &val);
2404     expect(Ok, status);
2405     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2406
2407     x = 9.25;
2408     y = 19.25;
2409     status = GdipIsVisiblePoint(graphics, x, y, &val);
2410     expect(Ok, status);
2411     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2412
2413     x = 9.5;
2414     y = 19.5;
2415     status = GdipIsVisiblePoint(graphics, x, y, &val);
2416     expect(Ok, status);
2417     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2418
2419     x = 9.75;
2420     y = 19.75;
2421     status = GdipIsVisiblePoint(graphics, x, y, &val);
2422     expect(Ok, status);
2423     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2424
2425     x = 10;
2426     y = 20;
2427     status = GdipIsVisiblePoint(graphics, x, y, &val);
2428     expect(Ok, status);
2429     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2430
2431     x = 40;
2432     y = 20;
2433     status = GdipIsVisiblePoint(graphics, x, y, &val);
2434     expect(Ok, status);
2435     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2436
2437     x = 39;
2438     y = 59;
2439     status = GdipIsVisiblePoint(graphics, x, y, &val);
2440     expect(Ok, status);
2441     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2442
2443     x = 39.25;
2444     y = 59.25;
2445     status = GdipIsVisiblePoint(graphics, x, y, &val);
2446     expect(Ok, status);
2447     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2448
2449     x = 39.5;
2450     y = 39.5;
2451     status = GdipIsVisiblePoint(graphics, x, y, &val);
2452     expect(Ok, status);
2453     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2454
2455     x = 39.75;
2456     y = 59.75;
2457     status = GdipIsVisiblePoint(graphics, x, y, &val);
2458     expect(Ok, status);
2459     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2460
2461     x = 40;
2462     y = 60;
2463     status = GdipIsVisiblePoint(graphics, x, y, &val);
2464     expect(Ok, status);
2465     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2466
2467     x = 40.15;
2468     y = 60.15;
2469     status = GdipIsVisiblePoint(graphics, x, y, &val);
2470     expect(Ok, status);
2471     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2472
2473     x = 10;
2474     y = 60;
2475     status = GdipIsVisiblePoint(graphics, x, y, &val);
2476     expect(Ok, status);
2477     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2478
2479     /* integer version */
2480     x = 25;
2481     y = 30;
2482     status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2483     expect(Ok, status);
2484     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2485
2486     x = 50;
2487     y = 100;
2488     status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2489     expect(Ok, status);
2490     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2491
2492     GdipDeleteGraphics(graphics);
2493     ReleaseDC(hwnd, hdc);
2494 }
2495
2496 static void test_GdipIsVisibleRect(void)
2497 {
2498     GpStatus status;
2499     GpGraphics *graphics = NULL;
2500     HDC hdc = GetDC( hwnd );
2501     REAL x, y, width, height;
2502     BOOL val;
2503
2504     ok(hdc != NULL, "Expected HDC to be initialized\n");
2505
2506     status = GdipCreateFromHDC(hdc, &graphics);
2507     expect(Ok, status);
2508     ok(graphics != NULL, "Expected graphics to be initialized\n");
2509
2510     status = GdipIsVisibleRect(NULL, 0, 0, 0, 0, &val);
2511     expect(InvalidParameter, status);
2512
2513     status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL);
2514     expect(InvalidParameter, status);
2515
2516     status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val);
2517     expect(InvalidParameter, status);
2518
2519     status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL);
2520     expect(InvalidParameter, status);
2521
2522     /* entirely within the visible region */
2523     x = 0; width = 10;
2524     y = 0; height = 10;
2525     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2526     expect(Ok, status);
2527     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2528
2529     /* partially outside */
2530     x = -10; width = 20;
2531     y = -10; height = 20;
2532     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2533     expect(Ok, status);
2534     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2535
2536     /* entirely outside */
2537     x = -10; width = 5;
2538     y = -10; height = 5;
2539     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2540     expect(Ok, status);
2541     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2542
2543     status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2544     expect(Ok, status);
2545
2546     /* entirely within the visible region */
2547     x = 12; width = 10;
2548     y = 22; height = 10;
2549     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2550     expect(Ok, status);
2551     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2552
2553     /* partially outside */
2554     x = 35; width = 10;
2555     y = 55; height = 10;
2556     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2557     expect(Ok, status);
2558     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2559
2560     /* entirely outside */
2561     x = 45; width = 5;
2562     y = 65; height = 5;
2563     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2564     expect(Ok, status);
2565     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2566
2567     /* translate into center of clipping rect */
2568     GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2569
2570     x = 0; width = 10;
2571     y = 0; height = 10;
2572     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2573     expect(Ok, status);
2574     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2575
2576     x = 25; width = 5;
2577     y = 40; height = 5;
2578     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2579     expect(Ok, status);
2580     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2581
2582     GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2583
2584     /* corners entirely outside, but some intersections */
2585     x = 0; width = 70;
2586     y = 0; height = 90;
2587     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2588     expect(Ok, status);
2589     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2590
2591     x = 0; width = 70;
2592     y = 0; height = 30;
2593     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2594     expect(Ok, status);
2595     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2596
2597     x = 0; width = 30;
2598     y = 0; height = 90;
2599     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2600     expect(Ok, status);
2601     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2602
2603     /* edge cases */
2604     x = 0; width = 10;
2605     y = 20; height = 40;
2606     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2607     expect(Ok, status);
2608     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2609
2610     x = 10; width = 30;
2611     y = 0; height = 20;
2612     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2613     expect(Ok, status);
2614     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2615
2616     x = 40; width = 10;
2617     y = 20; height = 40;
2618     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2619     expect(Ok, status);
2620     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2621
2622     x = 10; width = 30;
2623     y = 60; height = 10;
2624     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2625     expect(Ok, status);
2626     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2627
2628     /* rounding tests */
2629     x = 0.4; width = 10.4;
2630     y = 20; height = 40;
2631     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2632     expect(Ok, status);
2633     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2634
2635     x = 10; width = 30;
2636     y = 0.4; height = 20.4;
2637     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2638     expect(Ok, status);
2639     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2640
2641     /* integer version */
2642     x = 0; width = 30;
2643     y = 0; height = 90;
2644     status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2645     expect(Ok, status);
2646     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2647
2648     x = 12; width = 10;
2649     y = 22; height = 10;
2650     status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2651     expect(Ok, status);
2652     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2653
2654     GdipDeleteGraphics(graphics);
2655     ReleaseDC(hwnd, hdc);
2656 }
2657
2658 static void test_GdipGetNearestColor(void)
2659 {
2660     GpStatus status;
2661     GpGraphics *graphics;
2662     GpBitmap *bitmap;
2663     ARGB color = 0xdeadbeef;
2664     HDC hdc = GetDC( hwnd );
2665
2666     /* create a graphics object */
2667     ok(hdc != NULL, "Expected HDC to be initialized\n");
2668
2669     status = GdipCreateFromHDC(hdc, &graphics);
2670     expect(Ok, status);
2671     ok(graphics != NULL, "Expected graphics to be initialized\n");
2672
2673     status = GdipGetNearestColor(graphics, NULL);
2674     expect(InvalidParameter, status);
2675
2676     status = GdipGetNearestColor(NULL, &color);
2677     expect(InvalidParameter, status);
2678     GdipDeleteGraphics(graphics);
2679
2680     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, &bitmap);
2681     expect(Ok, status);
2682     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2683     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2684     if (status == Ok)
2685     {
2686         status = GdipGetNearestColor(graphics, &color);
2687         expect(Ok, status);
2688         expect(0xdeadbeef, color);
2689         GdipDeleteGraphics(graphics);
2690     }
2691     GdipDisposeImage((GpImage*)bitmap);
2692
2693     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, &bitmap);
2694     expect(Ok, status);
2695     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2696     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2697     if (status == Ok)
2698     {
2699         status = GdipGetNearestColor(graphics, &color);
2700         expect(Ok, status);
2701         expect(0xdeadbeef, color);
2702         GdipDeleteGraphics(graphics);
2703     }
2704     GdipDisposeImage((GpImage*)bitmap);
2705
2706     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, &bitmap);
2707     expect(Ok, status);
2708     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2709     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2710     if (status == Ok)
2711     {
2712         status = GdipGetNearestColor(graphics, &color);
2713         expect(Ok, status);
2714         expect(0xdeadbeef, color);
2715         GdipDeleteGraphics(graphics);
2716     }
2717     GdipDisposeImage((GpImage*)bitmap);
2718
2719     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, &bitmap);
2720     expect(Ok, status);
2721     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2722     todo_wine expect(OutOfMemory, status);
2723     if (status == Ok)
2724         GdipDeleteGraphics(graphics);
2725     GdipDisposeImage((GpImage*)bitmap);
2726
2727     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bitmap);
2728     expect(Ok, status);
2729     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2730     expect(Ok, status);
2731     status = GdipGetNearestColor(graphics, &color);
2732     expect(Ok, status);
2733     expect(0xdeadbeef, color);
2734     GdipDeleteGraphics(graphics);
2735     GdipDisposeImage((GpImage*)bitmap);
2736
2737     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, &bitmap);
2738     expect(Ok, status);
2739     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2740     expect(Ok, status);
2741     status = GdipGetNearestColor(graphics, &color);
2742     expect(Ok, status);
2743     expect(0xdeadbeef, color);
2744     GdipDeleteGraphics(graphics);
2745     GdipDisposeImage((GpImage*)bitmap);
2746
2747     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, &bitmap);
2748     expect(Ok, status);
2749     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2750     expect(Ok, status);
2751     status = GdipGetNearestColor(graphics, &color);
2752     expect(Ok, status);
2753     expect(0xdeadbeef, color);
2754     GdipDeleteGraphics(graphics);
2755     GdipDisposeImage((GpImage*)bitmap);
2756
2757     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, &bitmap);
2758     expect(Ok, status);
2759     if (status == Ok)
2760     {
2761         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2762         expect(Ok, status);
2763         status = GdipGetNearestColor(graphics, &color);
2764         expect(Ok, status);
2765         expect(0xdeadbeef, color);
2766         GdipDeleteGraphics(graphics);
2767         GdipDisposeImage((GpImage*)bitmap);
2768     }
2769
2770     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, &bitmap);
2771     expect(Ok, status);
2772     if (status == Ok)
2773     {
2774         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2775         expect(Ok, status);
2776         status = GdipGetNearestColor(graphics, &color);
2777         expect(Ok, status);
2778         expect(0xdeadbeef, color);
2779         GdipDeleteGraphics(graphics);
2780         GdipDisposeImage((GpImage*)bitmap);
2781     }
2782
2783     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, &bitmap);
2784     expect(Ok, status);
2785     if (status == Ok)
2786     {
2787         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2788         expect(Ok, status);
2789         status = GdipGetNearestColor(graphics, &color);
2790         expect(Ok, status);
2791         expect(0xdeadbeef, color);
2792         GdipDeleteGraphics(graphics);
2793         GdipDisposeImage((GpImage*)bitmap);
2794     }
2795
2796     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, &bitmap);
2797     expect(Ok, status);
2798     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2799     expect(Ok, status);
2800     status = GdipGetNearestColor(graphics, &color);
2801     expect(Ok, status);
2802     todo_wine expect(0xffa8bce8, color);
2803     GdipDeleteGraphics(graphics);
2804     GdipDisposeImage((GpImage*)bitmap);
2805
2806     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, &bitmap);
2807     expect(Ok, status);
2808     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2809     expect(Ok, status);
2810     status = GdipGetNearestColor(graphics, &color);
2811     expect(Ok, status);
2812     todo_wine
2813     ok(color == 0xffa8b8e8 ||
2814        broken(color == 0xffa0b8e0), /* Win98/WinMe */
2815        "Expected ffa8b8e8, got %.8x\n", color);
2816     GdipDeleteGraphics(graphics);
2817     GdipDisposeImage((GpImage*)bitmap);
2818
2819     ReleaseDC(hwnd, hdc);
2820 }
2821
2822 static void test_string_functions(void)
2823 {
2824     GpStatus status;
2825     GpGraphics *graphics;
2826     GpFontFamily *family;
2827     GpFont *font;
2828     RectF rc, char_bounds, bounds;
2829     GpBrush *brush;
2830     ARGB color = 0xff000000;
2831     HDC hdc = GetDC( hwnd );
2832     const WCHAR fontname[] = {'T','a','h','o','m','a',0};
2833     const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
2834     const WCHAR teststring2[] = {'j',0};
2835     REAL char_width, char_height;
2836     INT codepointsfitted, linesfilled;
2837     GpStringFormat *format;
2838     CharacterRange ranges[3] = {{0, 1}, {1, 3}, {5, 1}};
2839     GpRegion *regions[4] = {0};
2840     BOOL region_isempty[4];
2841     int i;
2842     PointF position;
2843     GpMatrix *identity;
2844
2845     ok(hdc != NULL, "Expected HDC to be initialized\n");
2846     status = GdipCreateFromHDC(hdc, &graphics);
2847     expect(Ok, status);
2848     ok(graphics != NULL, "Expected graphics to be initialized\n");
2849
2850     status = GdipCreateFontFamilyFromName(fontname, NULL, &family);
2851     expect(Ok, status);
2852
2853     status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font);
2854     expect(Ok, status);
2855
2856     status = GdipCreateSolidFill(color, (GpSolidFill**)&brush);
2857     expect(Ok, status);
2858
2859     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
2860     expect(Ok, status);
2861
2862     rc.X = 0;
2863     rc.Y = 0;
2864     rc.Width = 100.0;
2865     rc.Height = 100.0;
2866
2867     status = GdipDrawString(NULL, teststring, 6, font, &rc, NULL, brush);
2868     expect(InvalidParameter, status);
2869
2870     status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush);
2871     expect(InvalidParameter, status);
2872
2873     status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush);
2874     expect(InvalidParameter, status);
2875
2876     status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush);
2877     expect(InvalidParameter, status);
2878
2879     status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL);
2880     expect(InvalidParameter, status);
2881
2882     status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, brush);
2883     expect(Ok, status);
2884
2885     status = GdipMeasureString(NULL, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2886     expect(InvalidParameter, status);
2887
2888     status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2889     expect(InvalidParameter, status);
2890
2891     status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2892     expect(InvalidParameter, status);
2893
2894     status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled);
2895     expect(InvalidParameter, status);
2896
2897     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled);
2898     expect(InvalidParameter, status);
2899
2900     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, NULL, &linesfilled);
2901     expect(Ok, status);
2902
2903     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, NULL);
2904     expect(Ok, status);
2905
2906     status = GdipMeasureString(graphics, teststring, 1, font, &rc, NULL, &char_bounds, &codepointsfitted, &linesfilled);
2907     expect(Ok, status);
2908     expectf(0.0, char_bounds.X);
2909     expectf(0.0, char_bounds.Y);
2910     ok(char_bounds.Width > 0, "got %0.2f\n", bounds.Width);
2911     ok(char_bounds.Height > 0, "got %0.2f\n", bounds.Height);
2912     expect(1, codepointsfitted);
2913     expect(1, linesfilled);
2914
2915     status = GdipMeasureString(graphics, teststring, 2, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2916     expect(Ok, status);
2917     expectf(0.0, bounds.X);
2918     expectf(0.0, bounds.Y);
2919     ok(bounds.Width > char_bounds.Width, "got %0.2f, expected at least %0.2f\n", bounds.Width, char_bounds.Width);
2920     expectf(char_bounds.Height, bounds.Height);
2921     expect(2, codepointsfitted);
2922     expect(1, linesfilled);
2923     char_width = bounds.Width - char_bounds.Width;
2924
2925     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2926     expect(Ok, status);
2927     expectf(0.0, bounds.X);
2928     expectf(0.0, bounds.Y);
2929     ok(bounds.Width > char_bounds.Width + char_width * 2, "got %0.2f, expected at least %0.2f\n",
2930        bounds.Width, char_bounds.Width + char_width * 2);
2931     ok(bounds.Height > char_bounds.Height, "got %0.2f, expected at least %0.2f\n", bounds.Height, char_bounds.Height);
2932     expect(6, codepointsfitted);
2933     expect(2, linesfilled);
2934     char_height = bounds.Height - char_bounds.Height;
2935
2936     /* Cut off everything after the first space. */
2937     rc.Width = char_bounds.Width + char_width * 2.1;
2938
2939     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2940     expect(Ok, status);
2941     expectf(0.0, bounds.X);
2942     expectf(0.0, bounds.Y);
2943     expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
2944     expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
2945     expect(6, codepointsfitted);
2946     expect(3, linesfilled);
2947
2948     /* Cut off everything including the first space. */
2949     rc.Width = char_bounds.Width + char_width * 1.5;
2950
2951     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2952     expect(Ok, status);
2953     expectf(0.0, bounds.X);
2954     expectf(0.0, bounds.Y);
2955     expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
2956     expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
2957     expect(6, codepointsfitted);
2958     expect(3, linesfilled);
2959
2960     /* Cut off everything after the first character. */
2961     rc.Width = char_bounds.Width + char_width * 0.5;
2962
2963     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2964     expect(Ok, status);
2965     expectf(0.0, bounds.X);
2966     expectf(0.0, bounds.Y);
2967     expectf_(char_bounds.Width, bounds.Width, 0.01);
2968     todo_wine expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
2969     expect(6, codepointsfitted);
2970     todo_wine expect(4, linesfilled);
2971
2972     status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
2973     expect(Ok, status);
2974
2975     rc.Width = 100.0;
2976
2977     for (i=0; i<4; i++)
2978     {
2979         status = GdipCreateRegion(&regions[i]);
2980         expect(Ok, status);
2981     }
2982
2983     status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions);
2984     expect(InvalidParameter, status);
2985
2986     status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
2987     expect(InvalidParameter, status);
2988
2989     status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
2990     expect(InvalidParameter, status);
2991
2992     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
2993     expect(InvalidParameter, status);
2994
2995     if (0)
2996     {
2997         /* Crashes on Windows XP */
2998         status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
2999         expect(InvalidParameter, status);
3000     }
3001
3002     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL);
3003     expect(InvalidParameter, status);
3004
3005     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions);
3006     expect(InvalidParameter, status);
3007
3008     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions);
3009     expect(Ok, status);
3010
3011     for (i=0; i<4; i++)
3012     {
3013         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3014         expect(Ok, status);
3015     }
3016
3017     ok(!region_isempty[0], "region shouldn't be empty\n");
3018     ok(!region_isempty[1], "region shouldn't be empty\n");
3019     ok(!region_isempty[2], "region shouldn't be empty\n");
3020     ok(!region_isempty[3], "region shouldn't be empty\n");
3021
3022     /* Cut off everything after the first space, and the second line. */
3023     rc.Width = char_bounds.Width + char_width * 2.1;
3024     rc.Height = char_bounds.Height + char_height * 0.5;
3025
3026     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3027     expect(Ok, status);
3028
3029     for (i=0; i<4; i++)
3030     {
3031         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3032         expect(Ok, status);
3033     }
3034
3035     ok(!region_isempty[0], "region shouldn't be empty\n");
3036     ok(!region_isempty[1], "region shouldn't be empty\n");
3037     ok(region_isempty[2], "region should be empty\n");
3038     ok(!region_isempty[3], "region shouldn't be empty\n");
3039
3040     for (i=0; i<4; i++)
3041         GdipDeleteRegion(regions[i]);
3042
3043     status = GdipCreateMatrix(&identity);
3044     expect(Ok, status);
3045
3046     position.X = 0;
3047     position.Y = 0;
3048
3049     rc.X = 0;
3050     rc.Y = 0;
3051     rc.Width = 0;
3052     rc.Height = 0;
3053     status = GdipMeasureDriverString(NULL, teststring, 6, font, &position,
3054         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3055         identity, &rc);
3056     expect(InvalidParameter, status);
3057
3058     status = GdipMeasureDriverString(graphics, NULL, 6, font, &position,
3059         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3060         identity, &rc);
3061     expect(InvalidParameter, status);
3062
3063     status = GdipMeasureDriverString(graphics, teststring, 6, NULL, &position,
3064         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3065         identity, &rc);
3066     expect(InvalidParameter, status);
3067
3068     status = GdipMeasureDriverString(graphics, teststring, 6, font, NULL,
3069         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3070         identity, &rc);
3071     expect(InvalidParameter, status);
3072
3073     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3074         0x100, identity, &rc);
3075     expect(Ok, status);
3076
3077     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3078         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3079         NULL, &rc);
3080     expect(Ok, status);
3081
3082     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3083         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3084         identity, NULL);
3085     expect(InvalidParameter, status);
3086
3087     rc.X = 0;
3088     rc.Y = 0;
3089     rc.Width = 0;
3090     rc.Height = 0;
3091     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3092         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3093         identity, &rc);
3094     expect(Ok, status);
3095
3096     expectf(0.0, rc.X);
3097     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3098     ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width);
3099     ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y);
3100
3101     char_width = rc.Width;
3102     char_height = rc.Height;
3103
3104     rc.X = 0;
3105     rc.Y = 0;
3106     rc.Width = 0;
3107     rc.Height = 0;
3108     status = GdipMeasureDriverString(graphics, teststring, 4, font, &position,
3109         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3110         identity, &rc);
3111     expect(Ok, status);
3112
3113     expectf(0.0, rc.X);
3114     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3115     ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width);
3116     expectf(char_height, rc.Height);
3117
3118     rc.X = 0;
3119     rc.Y = 0;
3120     rc.Width = 0;
3121     rc.Height = 0;
3122     status = GdipMeasureDriverString(graphics, teststring2, 1, font, &position,
3123         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3124         identity, &rc);
3125     expect(Ok, status);
3126
3127     expectf(rc.X, 0.0);
3128     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3129     ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width);
3130     expectf(rc.Height, char_height);
3131
3132     GdipDeleteMatrix(identity);
3133     GdipDeleteStringFormat(format);
3134     GdipDeleteBrush(brush);
3135     GdipDeleteFont(font);
3136     GdipDeleteFontFamily(family);
3137     GdipDeleteGraphics(graphics);
3138
3139     ReleaseDC(hwnd, hdc);
3140 }
3141
3142 static void test_get_set_interpolation(void)
3143 {
3144     GpGraphics *graphics;
3145     HDC hdc = GetDC( hwnd );
3146     GpStatus status;
3147     InterpolationMode mode;
3148
3149     ok(hdc != NULL, "Expected HDC to be initialized\n");
3150     status = GdipCreateFromHDC(hdc, &graphics);
3151     expect(Ok, status);
3152     ok(graphics != NULL, "Expected graphics to be initialized\n");
3153
3154     status = GdipGetInterpolationMode(NULL, &mode);
3155     expect(InvalidParameter, status);
3156
3157     if (0)
3158     {
3159         /* Crashes on Windows XP */
3160         status = GdipGetInterpolationMode(graphics, NULL);
3161         expect(InvalidParameter, status);
3162     }
3163
3164     status = GdipSetInterpolationMode(NULL, InterpolationModeNearestNeighbor);
3165     expect(InvalidParameter, status);
3166
3167     /* out of range */
3168     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBicubic+1);
3169     expect(InvalidParameter, status);
3170
3171     status = GdipSetInterpolationMode(graphics, InterpolationModeInvalid);
3172     expect(InvalidParameter, status);
3173
3174     status = GdipGetInterpolationMode(graphics, &mode);
3175     expect(Ok, status);
3176     expect(InterpolationModeBilinear, mode);
3177
3178     status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3179     expect(Ok, status);
3180
3181     status = GdipGetInterpolationMode(graphics, &mode);
3182     expect(Ok, status);
3183     expect(InterpolationModeNearestNeighbor, mode);
3184
3185     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
3186     expect(Ok, status);
3187
3188     status = GdipGetInterpolationMode(graphics, &mode);
3189     expect(Ok, status);
3190     expect(InterpolationModeBilinear, mode);
3191
3192     status = GdipSetInterpolationMode(graphics, InterpolationModeLowQuality);
3193     expect(Ok, status);
3194
3195     status = GdipGetInterpolationMode(graphics, &mode);
3196     expect(Ok, status);
3197     expect(InterpolationModeBilinear, mode);
3198
3199     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality);
3200     expect(Ok, status);
3201
3202     status = GdipGetInterpolationMode(graphics, &mode);
3203     expect(Ok, status);
3204     expect(InterpolationModeHighQualityBicubic, mode);
3205
3206     GdipDeleteGraphics(graphics);
3207
3208     ReleaseDC(hwnd, hdc);
3209 }
3210
3211 static void test_get_set_textrenderinghint(void)
3212 {
3213     GpGraphics *graphics;
3214     HDC hdc = GetDC( hwnd );
3215     GpStatus status;
3216     TextRenderingHint hint;
3217
3218     ok(hdc != NULL, "Expected HDC to be initialized\n");
3219     status = GdipCreateFromHDC(hdc, &graphics);
3220     expect(Ok, status);
3221     ok(graphics != NULL, "Expected graphics to be initialized\n");
3222
3223     status = GdipGetTextRenderingHint(NULL, &hint);
3224     expect(InvalidParameter, status);
3225
3226     status = GdipGetTextRenderingHint(graphics, NULL);
3227     expect(InvalidParameter, status);
3228
3229     status = GdipSetTextRenderingHint(NULL, TextRenderingHintAntiAlias);
3230     expect(InvalidParameter, status);
3231
3232     /* out of range */
3233     status = GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit+1);
3234     expect(InvalidParameter, status);
3235
3236     status = GdipGetTextRenderingHint(graphics, &hint);
3237     expect(Ok, status);
3238     expect(TextRenderingHintSystemDefault, hint);
3239
3240     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
3241     expect(Ok, status);
3242
3243     status = GdipGetTextRenderingHint(graphics, &hint);
3244     expect(Ok, status);
3245     expect(TextRenderingHintSystemDefault, hint);
3246
3247     status = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAliasGridFit);
3248     expect(Ok, status);
3249
3250     status = GdipGetTextRenderingHint(graphics, &hint);
3251     expect(Ok, status);
3252     expect(TextRenderingHintAntiAliasGridFit, hint);
3253
3254     GdipDeleteGraphics(graphics);
3255
3256     ReleaseDC(hwnd, hdc);
3257 }
3258
3259 static void test_getdc_scaled(void)
3260 {
3261     GpStatus status;
3262     GpGraphics *graphics = NULL;
3263     GpBitmap *bitmap = NULL;
3264     HDC hdc=NULL;
3265     HBRUSH hbrush, holdbrush;
3266     ARGB color;
3267
3268     status = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, NULL, &bitmap);
3269     expect(Ok, status);
3270
3271     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
3272     expect(Ok, status);
3273
3274     status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
3275     expect(Ok, status);
3276
3277     status = GdipGetDC(graphics, &hdc);
3278     expect(Ok, status);
3279     ok(hdc != NULL, "got NULL hdc\n");
3280
3281     hbrush = CreateSolidBrush(RGB(255, 0, 0));
3282
3283     holdbrush = SelectObject(hdc, hbrush);
3284
3285     Rectangle(hdc, 2, 2, 6, 6);
3286
3287     SelectObject(hdc, holdbrush);
3288
3289     DeleteObject(hbrush);
3290
3291     status = GdipReleaseDC(graphics, hdc);
3292     expect(Ok, status);
3293
3294     GdipDeleteGraphics(graphics);
3295
3296     status = GdipBitmapGetPixel(bitmap, 3, 3, &color);
3297     expect(Ok, status);
3298     expect(0xffff0000, color);
3299
3300     status = GdipBitmapGetPixel(bitmap, 8, 8, &color);
3301     expect(Ok, status);
3302     expect(0xff000000, color);
3303
3304     GdipDisposeImage((GpImage*)bitmap);
3305 }
3306
3307 START_TEST(graphics)
3308 {
3309     struct GdiplusStartupInput gdiplusStartupInput;
3310     ULONG_PTR gdiplusToken;
3311     WNDCLASSA class;
3312
3313     memset( &class, 0, sizeof(class) );
3314     class.lpszClassName = "gdiplus_test";
3315     class.style = CS_HREDRAW | CS_VREDRAW;
3316     class.lpfnWndProc = DefWindowProcA;
3317     class.hInstance = GetModuleHandleA(0);
3318     class.hIcon = LoadIcon(0, IDI_APPLICATION);
3319     class.hCursor = LoadCursor(NULL, IDC_ARROW);
3320     class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
3321     RegisterClassA( &class );
3322     hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3323                           CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 );
3324     ok(hwnd != NULL, "Expected window to be created\n");
3325
3326     gdiplusStartupInput.GdiplusVersion              = 1;
3327     gdiplusStartupInput.DebugEventCallback          = NULL;
3328     gdiplusStartupInput.SuppressBackgroundThread    = 0;
3329     gdiplusStartupInput.SuppressExternalCodecs      = 0;
3330
3331     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
3332
3333     test_constructor_destructor();
3334     test_save_restore();
3335     test_GdipFillClosedCurve2();
3336     test_GdipFillClosedCurve2I();
3337     test_GdipDrawBezierI();
3338     test_GdipDrawArc();
3339     test_GdipDrawArcI();
3340     test_GdipDrawCurve();
3341     test_GdipDrawCurveI();
3342     test_GdipDrawCurve2();
3343     test_GdipDrawCurve2I();
3344     test_GdipDrawCurve3();
3345     test_GdipDrawCurve3I();
3346     test_GdipDrawLineI();
3347     test_GdipDrawLinesI();
3348     test_GdipDrawImagePointsRect();
3349     test_GdipFillClosedCurve();
3350     test_GdipFillClosedCurveI();
3351     test_GdipDrawString();
3352     test_GdipGetNearestColor();
3353     test_GdipGetVisibleClipBounds();
3354     test_GdipIsVisiblePoint();
3355     test_GdipIsVisibleRect();
3356     test_Get_Release_DC();
3357     test_BeginContainer2();
3358     test_transformpoints();
3359     test_get_set_clip();
3360     test_isempty();
3361     test_clear();
3362     test_textcontrast();
3363     test_fromMemoryBitmap();
3364     test_string_functions();
3365     test_get_set_interpolation();
3366     test_get_set_textrenderinghint();
3367     test_getdc_scaled();
3368
3369     GdiplusShutdown(gdiplusToken);
3370     DestroyWindow( hwnd );
3371 }