include: Assorted spelling fixes.
[wine] / dlls / gdiplus / tests / graphics.c
1 /*
2  * Unit test suite for graphics objects
3  *
4  * Copyright (C) 2007 Google (Evan Stade)
5  * Copyright (C) 2012 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <math.h>
23 #include <assert.h>
24
25 #include "windows.h"
26 #include "gdiplus.h"
27 #include "wingdi.h"
28 #include "wine/test.h"
29
30 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (INT)(expected), (INT)(got))
31 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
32 #define expectf(expected, got) expectf_((expected), (got), 0.001)
33 #define TABLE_LEN (23)
34
35 static const REAL mm_per_inch = 25.4;
36 static const REAL point_per_inch = 72.0;
37 static HWND hwnd;
38
39 static void set_rect_empty(RectF *rc)
40 {
41     rc->X = 0.0;
42     rc->Y = 0.0;
43     rc->Width = 0.0;
44     rc->Height = 0.0;
45 }
46
47 /* converts a given unit to its value in pixels */
48 static REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
49 {
50     switch (unit)
51     {
52     case UnitPixel:
53     case UnitDisplay:
54         return units;
55     case UnitPoint:
56         return units * dpi / point_per_inch;
57     case UnitInch:
58         return units * dpi;
59     case UnitDocument:
60         return units * dpi / 300.0; /* Per MSDN */
61     case UnitMillimeter:
62         return units * dpi / mm_per_inch;
63     default:
64         assert(0);
65         return 0;
66     }
67 }
68
69 /* converts value in pixels to a given unit */
70 static REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
71 {
72     switch (unit)
73     {
74     case UnitPixel:
75     case UnitDisplay:
76         return pixels;
77     case UnitPoint:
78         return pixels * point_per_inch / dpi;
79     case UnitInch:
80         return pixels / dpi;
81     case UnitDocument:
82         return pixels * 300.0 / dpi;
83     case UnitMillimeter:
84         return pixels * mm_per_inch / dpi;
85     default:
86         assert(0);
87         return 0;
88     }
89 }
90
91 static REAL units_scale(GpUnit from, GpUnit to, REAL dpi)
92 {
93     REAL pixels = units_to_pixels(1.0, from, dpi);
94     return pixels_to_units(pixels, to, dpi);
95 }
96
97 static GpGraphics *create_graphics(REAL res_x, REAL res_y, GpUnit unit, REAL scale)
98 {
99     GpStatus status;
100     union
101     {
102         GpBitmap *bitmap;
103         GpImage *image;
104     } u;
105     GpGraphics *graphics = NULL;
106     REAL res;
107
108     status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, NULL, &u.bitmap);
109     expect(Ok, status);
110
111     status = GdipBitmapSetResolution(u.bitmap, res_x, res_y);
112     expect(Ok, status);
113     status = GdipGetImageHorizontalResolution(u.image, &res);
114     expect(Ok, status);
115     expectf(res_x, res);
116     status = GdipGetImageVerticalResolution(u.image, &res);
117     expect(Ok, status);
118     expectf(res_y, res);
119
120     status = GdipGetImageGraphicsContext(u.image, &graphics);
121     expect(Ok, status);
122     /* image is intentionally leaked to make sure that there is no
123        side effects after its destruction.
124     status = GdipDisposeImage(u.image);
125     expect(Ok, status);
126     */
127
128     status = GdipGetDpiX(graphics, &res);
129     expect(Ok, status);
130     expectf(res_x, res);
131     status = GdipGetDpiY(graphics, &res);
132     expect(Ok, status);
133     expectf(res_y, res);
134
135     status = GdipSetPageUnit(graphics, unit);
136     expect(Ok, status);
137     status = GdipSetPageScale(graphics, scale);
138     expect(Ok, status);
139
140     return graphics;
141 }
142
143 static void test_constructor_destructor(void)
144 {
145     GpStatus stat;
146     GpGraphics *graphics = NULL;
147     HDC hdc = GetDC( hwnd );
148
149     stat = GdipCreateFromHDC(NULL, &graphics);
150     expect(OutOfMemory, stat);
151     stat = GdipDeleteGraphics(graphics);
152     expect(InvalidParameter, stat);
153
154     stat = GdipCreateFromHDC(hdc, &graphics);
155     expect(Ok, stat);
156     stat = GdipDeleteGraphics(graphics);
157     expect(Ok, stat);
158
159     stat = GdipCreateFromHWND(NULL, &graphics);
160     expect(Ok, stat);
161     stat = GdipDeleteGraphics(graphics);
162     expect(Ok, stat);
163
164     stat = GdipCreateFromHWNDICM(NULL, &graphics);
165     expect(Ok, stat);
166     stat = GdipDeleteGraphics(graphics);
167     expect(Ok, stat);
168
169     stat = GdipDeleteGraphics(NULL);
170     expect(InvalidParameter, stat);
171     ReleaseDC(hwnd, hdc);
172 }
173
174 typedef struct node{
175     GraphicsState data;
176     struct node * next;
177 } node;
178
179 /* Linked list prepend function. */
180 static void log_state(GraphicsState data, node ** log)
181 {
182     node * new_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(node));
183
184     new_entry->data = data;
185     new_entry->next = *log;
186     *log = new_entry;
187 }
188
189 /* Checks if there are duplicates in the list, and frees it. */
190 static void check_no_duplicates(node * log)
191 {
192     INT dups = 0;
193     node * temp = NULL;
194     node * temp2 = NULL;
195     node * orig = log;
196
197     if(!log)
198         goto end;
199
200     do{
201         temp = log;
202         while((temp = temp->next)){
203             if(log->data == temp->data){
204                 dups++;
205                 break;
206             }
207             if(dups > 0)
208                 break;
209         }
210     }while((log = log->next));
211
212     temp = orig;
213     do{
214         temp2 = temp->next;
215         HeapFree(GetProcessHeap(), 0, temp);
216         temp = temp2;
217     }while(temp);
218
219 end:
220     expect(0, dups);
221 }
222
223 static void test_save_restore(void)
224 {
225     GpStatus stat;
226     GraphicsState state_a, state_b, state_c;
227     InterpolationMode mode;
228     GpGraphics *graphics1, *graphics2;
229     node * state_log = NULL;
230     HDC hdc = GetDC( hwnd );
231     state_a = state_b = state_c = 0xdeadbeef;
232
233     /* Invalid saving. */
234     GdipCreateFromHDC(hdc, &graphics1);
235     stat = GdipSaveGraphics(graphics1, NULL);
236     expect(InvalidParameter, stat);
237     stat = GdipSaveGraphics(NULL, &state_a);
238     expect(InvalidParameter, stat);
239     GdipDeleteGraphics(graphics1);
240
241     log_state(state_a, &state_log);
242
243     /* Basic save/restore. */
244     GdipCreateFromHDC(hdc, &graphics1);
245     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
246     stat = GdipSaveGraphics(graphics1, &state_a);
247     expect(Ok, stat);
248     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
249     stat = GdipRestoreGraphics(graphics1, state_a);
250     expect(Ok, stat);
251     GdipGetInterpolationMode(graphics1, &mode);
252     expect(InterpolationModeBilinear, mode);
253     GdipDeleteGraphics(graphics1);
254
255     log_state(state_a, &state_log);
256
257     /* Restoring garbage doesn't affect saves. */
258     GdipCreateFromHDC(hdc, &graphics1);
259     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
260     GdipSaveGraphics(graphics1, &state_a);
261     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
262     GdipSaveGraphics(graphics1, &state_b);
263     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
264     stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
265     expect(Ok, stat);
266     GdipRestoreGraphics(graphics1, state_b);
267     GdipGetInterpolationMode(graphics1, &mode);
268     expect(InterpolationModeBicubic, mode);
269     GdipRestoreGraphics(graphics1, state_a);
270     GdipGetInterpolationMode(graphics1, &mode);
271     expect(InterpolationModeBilinear, mode);
272     GdipDeleteGraphics(graphics1);
273
274     log_state(state_a, &state_log);
275     log_state(state_b, &state_log);
276
277     /* Restoring older state invalidates newer saves (but not older saves). */
278     GdipCreateFromHDC(hdc, &graphics1);
279     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
280     GdipSaveGraphics(graphics1, &state_a);
281     GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
282     GdipSaveGraphics(graphics1, &state_b);
283     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
284     GdipSaveGraphics(graphics1, &state_c);
285     GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
286     GdipRestoreGraphics(graphics1, state_b);
287     GdipGetInterpolationMode(graphics1, &mode);
288     expect(InterpolationModeBicubic, mode);
289     GdipRestoreGraphics(graphics1, state_c);
290     GdipGetInterpolationMode(graphics1, &mode);
291     expect(InterpolationModeBicubic, mode);
292     GdipRestoreGraphics(graphics1, state_a);
293     GdipGetInterpolationMode(graphics1, &mode);
294     expect(InterpolationModeBilinear, mode);
295     GdipDeleteGraphics(graphics1);
296
297     log_state(state_a, &state_log);
298     log_state(state_b, &state_log);
299     log_state(state_c, &state_log);
300
301     /* Restoring older save from one graphics object does not invalidate
302      * newer save from other graphics object. */
303     GdipCreateFromHDC(hdc, &graphics1);
304     GdipCreateFromHDC(hdc, &graphics2);
305     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
306     GdipSaveGraphics(graphics1, &state_a);
307     GdipSetInterpolationMode(graphics2, InterpolationModeBicubic);
308     GdipSaveGraphics(graphics2, &state_b);
309     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
310     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
311     GdipRestoreGraphics(graphics1, state_a);
312     GdipGetInterpolationMode(graphics1, &mode);
313     expect(InterpolationModeBilinear, mode);
314     GdipRestoreGraphics(graphics2, state_b);
315     GdipGetInterpolationMode(graphics2, &mode);
316     expect(InterpolationModeBicubic, mode);
317     GdipDeleteGraphics(graphics1);
318     GdipDeleteGraphics(graphics2);
319
320     /* You can't restore a state to a graphics object that didn't save it. */
321     GdipCreateFromHDC(hdc, &graphics1);
322     GdipCreateFromHDC(hdc, &graphics2);
323     GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
324     GdipSaveGraphics(graphics1, &state_a);
325     GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
326     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
327     GdipRestoreGraphics(graphics2, state_a);
328     GdipGetInterpolationMode(graphics2, &mode);
329     expect(InterpolationModeNearestNeighbor, mode);
330     GdipDeleteGraphics(graphics1);
331     GdipDeleteGraphics(graphics2);
332
333     log_state(state_a, &state_log);
334
335     /* The same state value should never be returned twice. */
336     todo_wine
337         check_no_duplicates(state_log);
338
339     ReleaseDC(hwnd, hdc);
340 }
341
342 static void test_GdipFillClosedCurve2(void)
343 {
344     GpStatus status;
345     GpGraphics *graphics = NULL;
346     GpSolidFill *brush = NULL;
347     HDC hdc = GetDC( hwnd );
348     GpPointF points[3];
349
350     points[0].X = 0;
351     points[0].Y = 0;
352
353     points[1].X = 40;
354     points[1].Y = 20;
355
356     points[2].X = 10;
357     points[2].Y = 40;
358
359     /* make a graphics object and brush object */
360     ok(hdc != NULL, "Expected HDC to be initialized\n");
361
362     status = GdipCreateFromHDC(hdc, &graphics);
363     expect(Ok, status);
364     ok(graphics != NULL, "Expected graphics to be initialized\n");
365
366     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
367
368     /* InvalidParameter cases: null graphics, null brush, null points */
369     status = GdipFillClosedCurve2(NULL, NULL, NULL, 3, 0.5, FillModeAlternate);
370     expect(InvalidParameter, status);
371
372     status = GdipFillClosedCurve2(graphics, NULL, NULL, 3, 0.5, FillModeAlternate);
373     expect(InvalidParameter, status);
374
375     status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
376     expect(InvalidParameter, status);
377
378     status = GdipFillClosedCurve2(NULL, NULL, points, 3, 0.5, FillModeAlternate);
379     expect(InvalidParameter, status);
380
381     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
382     expect(InvalidParameter, status);
383
384     status = GdipFillClosedCurve2(graphics, NULL, points, 3, 0.5, FillModeAlternate);
385     expect(InvalidParameter, status);
386
387     status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
388     expect(InvalidParameter, status);
389
390     /* InvalidParameter cases: invalid count */
391     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
392     expect(InvalidParameter, status);
393
394     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
395     expect(InvalidParameter, status);
396
397     /* Valid test cases */
398     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
399     expect(Ok, status);
400
401     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
402     expect(Ok, status);
403
404     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
405     expect(Ok, status);
406
407     GdipDeleteGraphics(graphics);
408     GdipDeleteBrush((GpBrush*)brush);
409
410     ReleaseDC(hwnd, hdc);
411 }
412
413 static void test_GdipFillClosedCurve2I(void)
414 {
415     GpStatus status;
416     GpGraphics *graphics = NULL;
417     GpSolidFill *brush = NULL;
418     HDC hdc = GetDC( hwnd );
419     GpPoint points[3];
420
421     points[0].X = 0;
422     points[0].Y = 0;
423
424     points[1].X = 40;
425     points[1].Y = 20;
426
427     points[2].X = 10;
428     points[2].Y = 40;
429
430     /* make a graphics object and brush object */
431     ok(hdc != NULL, "Expected HDC to be initialized\n");
432
433     status = GdipCreateFromHDC(hdc, &graphics);
434     expect(Ok, status);
435     ok(graphics != NULL, "Expected graphics to be initialized\n");
436
437     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
438
439     /* InvalidParameter cases: null graphics, null brush */
440     /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
441              when points == NULL, so don't test this condition */
442     status = GdipFillClosedCurve2I(NULL, NULL, points, 3, 0.5, FillModeAlternate);
443     expect(InvalidParameter, status);
444
445     status = GdipFillClosedCurve2I(graphics, NULL, points, 3, 0.5, FillModeAlternate);
446     expect(InvalidParameter, status);
447
448     status = GdipFillClosedCurve2I(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
449     expect(InvalidParameter, status);
450
451     /* InvalidParameter cases: invalid count */
452     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
453     expect(InvalidParameter, status);
454
455     /* OutOfMemory cases: large (unsigned) int */
456     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
457     expect(OutOfMemory, status);
458
459     /* Valid test cases */
460     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
461     expect(Ok, status);
462
463     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
464     expect(Ok, status);
465
466     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
467     expect(Ok, status);
468
469     GdipDeleteGraphics(graphics);
470     GdipDeleteBrush((GpBrush*)brush);
471
472     ReleaseDC(hwnd, hdc);
473 }
474
475 static void test_GdipDrawArc(void)
476 {
477     GpStatus status;
478     GpGraphics *graphics = NULL;
479     GpPen *pen = NULL;
480     HDC hdc = GetDC( hwnd );
481
482     /* make a graphics object and pen object */
483     ok(hdc != NULL, "Expected HDC to be initialized\n");
484
485     status = GdipCreateFromHDC(hdc, &graphics);
486     expect(Ok, status);
487     ok(graphics != NULL, "Expected graphics to be initialized\n");
488
489     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
490     expect(Ok, status);
491     ok(pen != NULL, "Expected pen to be initialized\n");
492
493     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
494     status = GdipDrawArc(NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
495     expect(InvalidParameter, status);
496
497     status = GdipDrawArc(graphics, NULL, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
498     expect(InvalidParameter, status);
499
500     status = GdipDrawArc(NULL, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
501     expect(InvalidParameter, status);
502
503     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
504     expect(InvalidParameter, status);
505
506     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
507     expect(InvalidParameter, status);
508
509     /* successful case */
510     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
511     expect(Ok, status);
512
513     GdipDeletePen(pen);
514     GdipDeleteGraphics(graphics);
515
516     ReleaseDC(hwnd, hdc);
517 }
518
519 static void test_GdipDrawArcI(void)
520 {
521     GpStatus status;
522     GpGraphics *graphics = NULL;
523     GpPen *pen = NULL;
524     HDC hdc = GetDC( hwnd );
525
526     /* make a graphics object and pen object */
527     ok(hdc != NULL, "Expected HDC to be initialized\n");
528
529     status = GdipCreateFromHDC(hdc, &graphics);
530     expect(Ok, status);
531     ok(graphics != NULL, "Expected graphics to be initialized\n");
532
533     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
534     expect(Ok, status);
535     ok(pen != NULL, "Expected pen to be initialized\n");
536
537     /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
538     status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
539     expect(InvalidParameter, status);
540
541     status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
542     expect(InvalidParameter, status);
543
544     status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
545     expect(InvalidParameter, status);
546
547     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
548     expect(InvalidParameter, status);
549
550     status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
551     expect(InvalidParameter, status);
552
553     /* successful case */
554     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
555     expect(Ok, status);
556
557     GdipDeletePen(pen);
558     GdipDeleteGraphics(graphics);
559
560     ReleaseDC(hwnd, hdc);
561 }
562
563 static void test_BeginContainer2(void)
564 {
565     GpMatrix *transform;
566     GpRectF clip;
567     REAL defClip[] = {5, 10, 15, 20};
568     REAL elems[6], defTrans[] = {1, 2, 3, 4, 5, 6};
569     GraphicsContainer cont1, cont2, cont3, cont4;
570     CompositingQuality compqual, defCompqual = CompositingQualityHighSpeed;
571     CompositingMode compmode, defCompmode = CompositingModeSourceOver;
572     InterpolationMode interp, defInterp = InterpolationModeHighQualityBicubic;
573     REAL scale, defScale = 17;
574     GpUnit unit, defUnit = UnitPixel;
575     PixelOffsetMode offsetmode, defOffsetmode = PixelOffsetModeHighSpeed;
576     SmoothingMode smoothmode, defSmoothmode = SmoothingModeAntiAlias;
577     UINT contrast, defContrast = 5;
578     TextRenderingHint texthint, defTexthint = TextRenderingHintAntiAlias;
579
580     GpStatus status;
581     GpGraphics *graphics = NULL;
582     HDC hdc = GetDC( hwnd );
583
584     ok(hdc != NULL, "Expected HDC to be initialized\n");
585
586     status = GdipCreateFromHDC(hdc, &graphics);
587     expect(Ok, status);
588     ok(graphics != NULL, "Expected graphics to be initialized\n");
589
590     /* null graphics, null container */
591     status = GdipBeginContainer2(NULL, &cont1);
592     expect(InvalidParameter, status);
593
594     status = GdipBeginContainer2(graphics, NULL);
595     expect(InvalidParameter, status);
596
597     status = GdipEndContainer(NULL, cont1);
598     expect(InvalidParameter, status);
599
600     /* test all quality-related values */
601     GdipSetCompositingMode(graphics, defCompmode);
602     GdipSetCompositingQuality(graphics, defCompqual);
603     GdipSetInterpolationMode(graphics, defInterp);
604     GdipSetPageScale(graphics, defScale);
605     GdipSetPageUnit(graphics, defUnit);
606     GdipSetPixelOffsetMode(graphics, defOffsetmode);
607     GdipSetSmoothingMode(graphics, defSmoothmode);
608     GdipSetTextContrast(graphics, defContrast);
609     GdipSetTextRenderingHint(graphics, defTexthint);
610
611     status = GdipBeginContainer2(graphics, &cont1);
612     expect(Ok, status);
613
614     GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
615     GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
616     GdipSetInterpolationMode(graphics, InterpolationModeBilinear);
617     GdipSetPageScale(graphics, 10);
618     GdipSetPageUnit(graphics, UnitDocument);
619     GdipSetPixelOffsetMode(graphics, PixelOffsetModeHalf);
620     GdipSetSmoothingMode(graphics, SmoothingModeNone);
621     GdipSetTextContrast(graphics, 7);
622     GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit);
623
624     status = GdipEndContainer(graphics, cont1);
625     expect(Ok, status);
626
627     GdipGetCompositingMode(graphics, &compmode);
628     ok(defCompmode == compmode, "Expected Compositing Mode to be restored to %d, got %d\n", defCompmode, compmode);
629
630     GdipGetCompositingQuality(graphics, &compqual);
631     ok(defCompqual == compqual, "Expected Compositing Quality to be restored to %d, got %d\n", defCompqual, compqual);
632
633     GdipGetInterpolationMode(graphics, &interp);
634     ok(defInterp == interp, "Expected Interpolation Mode to be restored to %d, got %d\n", defInterp, interp);
635
636     GdipGetPageScale(graphics, &scale);
637     ok(fabs(defScale - scale) < 0.0001, "Expected Page Scale to be restored to %f, got %f\n", defScale, scale);
638
639     GdipGetPageUnit(graphics, &unit);
640     ok(defUnit == unit, "Expected Page Unit to be restored to %d, got %d\n", defUnit, unit);
641
642     GdipGetPixelOffsetMode(graphics, &offsetmode);
643     ok(defOffsetmode == offsetmode, "Expected Pixel Offset Mode to be restored to %d, got %d\n", defOffsetmode, offsetmode);
644
645     GdipGetSmoothingMode(graphics, &smoothmode);
646     ok(defSmoothmode == smoothmode, "Expected Smoothing Mode to be restored to %d, got %d\n", defSmoothmode, smoothmode);
647
648     GdipGetTextContrast(graphics, &contrast);
649     ok(defContrast == contrast, "Expected Text Contrast to be restored to %d, got %d\n", defContrast, contrast);
650
651     GdipGetTextRenderingHint(graphics, &texthint);
652     ok(defTexthint == texthint, "Expected Text Hint to be restored to %d, got %d\n", defTexthint, texthint);
653
654     /* test world transform */
655     status = GdipBeginContainer2(graphics, &cont1);
656     expect(Ok, status);
657
658     status = GdipCreateMatrix2(defTrans[0], defTrans[1], defTrans[2], defTrans[3],
659             defTrans[4], defTrans[5], &transform);
660     expect(Ok, status);
661     GdipSetWorldTransform(graphics, transform);
662     GdipDeleteMatrix(transform);
663     transform = NULL;
664
665     status = GdipBeginContainer2(graphics, &cont2);
666     expect(Ok, status);
667
668     status = GdipCreateMatrix2(10, 20, 30, 40, 50, 60, &transform);
669     expect(Ok, status);
670     GdipSetWorldTransform(graphics, transform);
671     GdipDeleteMatrix(transform);
672     transform = NULL;
673
674     status = GdipEndContainer(graphics, cont2);
675     expect(Ok, status);
676
677     status = GdipCreateMatrix(&transform);
678     expect(Ok, status);
679     GdipGetWorldTransform(graphics, transform);
680     GdipGetMatrixElements(transform, elems);
681     ok(fabs(defTrans[0] - elems[0]) < 0.0001 &&
682             fabs(defTrans[1] - elems[1]) < 0.0001 &&
683             fabs(defTrans[2] - elems[2]) < 0.0001 &&
684             fabs(defTrans[3] - elems[3]) < 0.0001 &&
685             fabs(defTrans[4] - elems[4]) < 0.0001 &&
686             fabs(defTrans[5] - elems[5]) < 0.0001,
687             "Expected World Transform Matrix to be restored to [%f, %f, %f, %f, %f, %f], got [%f, %f, %f, %f, %f, %f]\n",
688             defTrans[0], defTrans[1], defTrans[2], defTrans[3], defTrans[4], defTrans[5],
689             elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
690     GdipDeleteMatrix(transform);
691     transform = NULL;
692
693     status = GdipEndContainer(graphics, cont1);
694     expect(Ok, status);
695
696     /* test clipping */
697     status = GdipBeginContainer2(graphics, &cont1);
698     expect(Ok, status);
699
700     GdipSetClipRect(graphics, defClip[0], defClip[1], defClip[2], defClip[3], CombineModeReplace);
701
702     status = GdipBeginContainer2(graphics, &cont2);
703     expect(Ok, status);
704
705     GdipSetClipRect(graphics, 2, 4, 6, 8, CombineModeReplace);
706
707     status = GdipEndContainer(graphics, cont2);
708     expect(Ok, status);
709
710     GdipGetClipBounds(graphics, &clip);
711     ok(fabs(defClip[0] - clip.X) < 0.0001 &&
712             fabs(defClip[1] - clip.Y) < 0.0001 &&
713             fabs(defClip[2] - clip.Width) < 0.0001 &&
714             fabs(defClip[3] - clip.Height) < 0.0001,
715             "Expected Clipping Rectangle to be restored to [%f, %f, %f, %f], got [%f, %f, %f, %f]\n",
716             defClip[0], defClip[1], defClip[2], defClip[3],
717             clip.X, clip.Y, clip.Width, clip.Height);
718
719     status = GdipEndContainer(graphics, cont1);
720     expect(Ok, status);
721
722     /* nesting */
723     status = GdipBeginContainer2(graphics, &cont1);
724     expect(Ok, status);
725
726     status = GdipBeginContainer2(graphics, &cont2);
727     expect(Ok, status);
728
729     status = GdipBeginContainer2(graphics, &cont3);
730     expect(Ok, status);
731
732     status = GdipEndContainer(graphics, cont3);
733     expect(Ok, status);
734
735     status = GdipBeginContainer2(graphics, &cont4);
736     expect(Ok, status);
737
738     status = GdipEndContainer(graphics, cont4);
739     expect(Ok, status);
740
741     /* skip cont2 */
742     status = GdipEndContainer(graphics, cont1);
743     expect(Ok, status);
744
745     /* end an already-ended container */
746     status = GdipEndContainer(graphics, cont1);
747     expect(Ok, status);
748
749     GdipDeleteGraphics(graphics);
750     ReleaseDC(hwnd, hdc);
751 }
752
753 static void test_GdipDrawBezierI(void)
754 {
755     GpStatus status;
756     GpGraphics *graphics = NULL;
757     GpPen *pen = NULL;
758     HDC hdc = GetDC( hwnd );
759
760     /* make a graphics object and pen object */
761     ok(hdc != NULL, "Expected HDC to be initialized\n");
762
763     status = GdipCreateFromHDC(hdc, &graphics);
764     expect(Ok, status);
765     ok(graphics != NULL, "Expected graphics to be initialized\n");
766
767     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
768     expect(Ok, status);
769     ok(pen != NULL, "Expected pen to be initialized\n");
770
771     /* InvalidParameter cases: null graphics, null pen */
772     status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
773     expect(InvalidParameter, status);
774
775     status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
776     expect(InvalidParameter, status);
777
778     status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
779     expect(InvalidParameter, status);
780
781     /* successful case */
782     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
783     expect(Ok, status);
784
785     GdipDeletePen(pen);
786     GdipDeleteGraphics(graphics);
787
788     ReleaseDC(hwnd, hdc);
789 }
790
791 static void test_GdipDrawCurve3(void)
792 {
793     GpStatus status;
794     GpGraphics *graphics = NULL;
795     GpPen *pen = NULL;
796     HDC hdc = GetDC( hwnd );
797     GpPointF points[3];
798
799     points[0].X = 0;
800     points[0].Y = 0;
801
802     points[1].X = 40;
803     points[1].Y = 20;
804
805     points[2].X = 10;
806     points[2].Y = 40;
807
808     /* make a graphics object and pen object */
809     ok(hdc != NULL, "Expected HDC to be initialized\n");
810
811     status = GdipCreateFromHDC(hdc, &graphics);
812     expect(Ok, status);
813     ok(graphics != NULL, "Expected graphics to be initialized\n");
814
815     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
816     expect(Ok, status);
817     ok(pen != NULL, "Expected pen to be initialized\n");
818
819     /* InvalidParameter cases: null graphics, null pen */
820     status = GdipDrawCurve3(NULL, NULL, points, 3, 0, 2, 1);
821     expect(InvalidParameter, status);
822
823     status = GdipDrawCurve3(graphics, NULL, points, 3, 0, 2, 1);
824     expect(InvalidParameter, status);
825
826     status = GdipDrawCurve3(NULL, pen, points, 3, 0, 2, 1);
827     expect(InvalidParameter, status);
828
829     /* InvalidParameter cases: invalid count */
830     status = GdipDrawCurve3(graphics, pen, points, -1, 0, 2, 1);
831     expect(InvalidParameter, status);
832
833     status = GdipDrawCurve3(graphics, pen, points, 0, 0, 2, 1);
834     expect(InvalidParameter, status);
835
836     status = GdipDrawCurve3(graphics, pen, points, 1, 0, 0, 1);
837     expect(InvalidParameter, status);
838
839     status = GdipDrawCurve3(graphics, pen, points, 3, 4, 2, 1);
840     expect(InvalidParameter, status);
841
842     /* InvalidParameter cases: invalid number of segments */
843     status = GdipDrawCurve3(graphics, pen, points, 3, 0, -1, 1);
844     expect(InvalidParameter, status);
845
846     status = GdipDrawCurve3(graphics, pen, points, 3, 1, 2, 1);
847     expect(InvalidParameter, status);
848
849     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 2, 1);
850     expect(InvalidParameter, status);
851
852     /* Valid test cases */
853     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, 1);
854     expect(Ok, status);
855
856     status = GdipDrawCurve3(graphics, pen, points, 3, 0, 2, 2);
857     expect(Ok, status);
858
859     status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, -2);
860     expect(Ok, status);
861
862     status = GdipDrawCurve3(graphics, pen, points, 3, 1, 1, 0);
863     expect(Ok, status);
864
865     GdipDeletePen(pen);
866     GdipDeleteGraphics(graphics);
867
868     ReleaseDC(hwnd, hdc);
869 }
870
871 static void test_GdipDrawCurve3I(void)
872 {
873     GpStatus status;
874     GpGraphics *graphics = NULL;
875     GpPen *pen = NULL;
876     HDC hdc = GetDC( hwnd );
877     GpPoint points[3];
878
879     points[0].X = 0;
880     points[0].Y = 0;
881
882     points[1].X = 40;
883     points[1].Y = 20;
884
885     points[2].X = 10;
886     points[2].Y = 40;
887
888     /* make a graphics object and pen object */
889     ok(hdc != NULL, "Expected HDC to be initialized\n");
890
891     status = GdipCreateFromHDC(hdc, &graphics);
892     expect(Ok, status);
893     ok(graphics != NULL, "Expected graphics to be initialized\n");
894
895     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
896     expect(Ok, status);
897     ok(pen != NULL, "Expected pen to be initialized\n");
898
899     /* InvalidParameter cases: null graphics, null pen */
900     status = GdipDrawCurve3I(NULL, NULL, points, 3, 0, 2, 1);
901     expect(InvalidParameter, status);
902
903     status = GdipDrawCurve3I(graphics, NULL, points, 3, 0, 2, 1);
904     expect(InvalidParameter, status);
905
906     status = GdipDrawCurve3I(NULL, pen, points, 3, 0, 2, 1);
907     expect(InvalidParameter, status);
908
909     /* InvalidParameter cases: invalid count */
910     status = GdipDrawCurve3I(graphics, pen, points, -1, -1, -1, 1);
911     expect(OutOfMemory, status);
912
913     status = GdipDrawCurve3I(graphics, pen, points, 0, 0, 2, 1);
914     expect(InvalidParameter, status);
915
916     status = GdipDrawCurve3I(graphics, pen, points, 1, 0, 0, 1);
917     expect(InvalidParameter, status);
918
919     status = GdipDrawCurve3I(graphics, pen, points, 3, 4, 2, 1);
920     expect(InvalidParameter, status);
921
922     /* InvalidParameter cases: invalid number of segments */
923     status = GdipDrawCurve3I(graphics, pen, points, 3, 0, -1, 1);
924     expect(InvalidParameter, status);
925
926     status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 2, 1);
927     expect(InvalidParameter, status);
928
929     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 2, 1);
930     expect(InvalidParameter, status);
931
932     /* Valid test cases */
933     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, 1);
934     expect(Ok, status);
935
936     status = GdipDrawCurve3I(graphics, pen, points, 3, 0, 2, 2);
937     expect(Ok, status);
938
939     status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, -2);
940     expect(Ok, status);
941
942     status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 1, 0);
943     expect(Ok, status);
944
945     GdipDeletePen(pen);
946     GdipDeleteGraphics(graphics);
947
948     ReleaseDC(hwnd, hdc);
949 }
950
951 static void test_GdipDrawCurve2(void)
952 {
953     GpStatus status;
954     GpGraphics *graphics = NULL;
955     GpPen *pen = NULL;
956     HDC hdc = GetDC( hwnd );
957     GpPointF points[3];
958
959     points[0].X = 0;
960     points[0].Y = 0;
961
962     points[1].X = 40;
963     points[1].Y = 20;
964
965     points[2].X = 10;
966     points[2].Y = 40;
967
968     /* make a graphics object and pen object */
969     ok(hdc != NULL, "Expected HDC to be initialized\n");
970
971     status = GdipCreateFromHDC(hdc, &graphics);
972     expect(Ok, status);
973     ok(graphics != NULL, "Expected graphics to be initialized\n");
974
975     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
976     expect(Ok, status);
977     ok(pen != NULL, "Expected pen to be initialized\n");
978
979     /* InvalidParameter cases: null graphics, null pen */
980     status = GdipDrawCurve2(NULL, NULL, points, 3, 1);
981     expect(InvalidParameter, status);
982
983     status = GdipDrawCurve2(graphics, NULL, points, 3, 1);
984     expect(InvalidParameter, status);
985
986     status = GdipDrawCurve2(NULL, pen, points, 3, 1);
987     expect(InvalidParameter, status);
988
989     /* InvalidParameter cases: invalid count */
990     status = GdipDrawCurve2(graphics, pen, points, -1, 1);
991     expect(InvalidParameter, status);
992
993     status = GdipDrawCurve2(graphics, pen, points, 0, 1);
994     expect(InvalidParameter, status);
995
996     status = GdipDrawCurve2(graphics, pen, points, 1, 1);
997     expect(InvalidParameter, status);
998
999     /* Valid test cases */
1000     status = GdipDrawCurve2(graphics, pen, points, 2, 1);
1001     expect(Ok, status);
1002
1003     status = GdipDrawCurve2(graphics, pen, points, 3, 2);
1004     expect(Ok, status);
1005
1006     status = GdipDrawCurve2(graphics, pen, points, 3, -2);
1007     expect(Ok, status);
1008
1009     status = GdipDrawCurve2(graphics, pen, points, 3, 0);
1010     expect(Ok, status);
1011
1012     GdipDeletePen(pen);
1013     GdipDeleteGraphics(graphics);
1014
1015     ReleaseDC(hwnd, hdc);
1016 }
1017
1018 static void test_GdipDrawCurve2I(void)
1019 {
1020     GpStatus status;
1021     GpGraphics *graphics = NULL;
1022     GpPen *pen = NULL;
1023     HDC hdc = GetDC( hwnd );
1024     GpPoint points[3];
1025
1026     points[0].X = 0;
1027     points[0].Y = 0;
1028
1029     points[1].X = 40;
1030     points[1].Y = 20;
1031
1032     points[2].X = 10;
1033     points[2].Y = 40;
1034
1035     /* make a graphics object and pen object */
1036     ok(hdc != NULL, "Expected HDC to be initialized\n");
1037
1038     status = GdipCreateFromHDC(hdc, &graphics);
1039     expect(Ok, status);
1040     ok(graphics != NULL, "Expected graphics to be initialized\n");
1041
1042     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1043     expect(Ok, status);
1044     ok(pen != NULL, "Expected pen to be initialized\n");
1045
1046     /* InvalidParameter cases: null graphics, null pen */
1047     status = GdipDrawCurve2I(NULL, NULL, points, 3, 1);
1048     expect(InvalidParameter, status);
1049
1050     status = GdipDrawCurve2I(graphics, NULL, points, 3, 1);
1051     expect(InvalidParameter, status);
1052
1053     status = GdipDrawCurve2I(NULL, pen, points, 3, 1);
1054     expect(InvalidParameter, status);
1055
1056     /* InvalidParameter cases: invalid count */
1057     status = GdipDrawCurve2I(graphics, pen, points, -1, 1);
1058     expect(OutOfMemory, status);
1059
1060     status = GdipDrawCurve2I(graphics, pen, points, 0, 1);
1061     expect(InvalidParameter, status);
1062
1063     status = GdipDrawCurve2I(graphics, pen, points, 1, 1);
1064     expect(InvalidParameter, status);
1065
1066     /* Valid test cases */
1067     status = GdipDrawCurve2I(graphics, pen, points, 2, 1);
1068     expect(Ok, status);
1069
1070     status = GdipDrawCurve2I(graphics, pen, points, 3, 2);
1071     expect(Ok, status);
1072
1073     status = GdipDrawCurve2I(graphics, pen, points, 3, -2);
1074     expect(Ok, status);
1075
1076     status = GdipDrawCurve2I(graphics, pen, points, 3, 0);
1077     expect(Ok, status);
1078
1079     GdipDeletePen(pen);
1080     GdipDeleteGraphics(graphics);
1081
1082     ReleaseDC(hwnd, hdc);
1083 }
1084
1085 static void test_GdipDrawCurve(void)
1086 {
1087     GpStatus status;
1088     GpGraphics *graphics = NULL;
1089     GpPen *pen = NULL;
1090     HDC hdc = GetDC( hwnd );
1091     GpPointF points[3];
1092
1093     points[0].X = 0;
1094     points[0].Y = 0;
1095
1096     points[1].X = 40;
1097     points[1].Y = 20;
1098
1099     points[2].X = 10;
1100     points[2].Y = 40;
1101
1102     /* make a graphics object and pen object */
1103     ok(hdc != NULL, "Expected HDC to be initialized\n");
1104
1105     status = GdipCreateFromHDC(hdc, &graphics);
1106     expect(Ok, status);
1107     ok(graphics != NULL, "Expected graphics to be initialized\n");
1108
1109     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1110     expect(Ok, status);
1111     ok(pen != NULL, "Expected pen to be initialized\n");
1112
1113     /* InvalidParameter cases: null graphics, null pen */
1114     status = GdipDrawCurve(NULL, NULL, points, 3);
1115     expect(InvalidParameter, status);
1116
1117     status = GdipDrawCurve(graphics, NULL, points, 3);
1118     expect(InvalidParameter, status);
1119
1120     status = GdipDrawCurve(NULL, pen, points, 3);
1121     expect(InvalidParameter, status);
1122
1123     /* InvalidParameter cases: invalid count */
1124     status = GdipDrawCurve(graphics, pen, points, -1);
1125     expect(InvalidParameter, status);
1126
1127     status = GdipDrawCurve(graphics, pen, points, 0);
1128     expect(InvalidParameter, status);
1129
1130     status = GdipDrawCurve(graphics, pen, points, 1);
1131     expect(InvalidParameter, status);
1132
1133     /* Valid test cases */
1134     status = GdipDrawCurve(graphics, pen, points, 2);
1135     expect(Ok, status);
1136
1137     status = GdipDrawCurve(graphics, pen, points, 3);
1138     expect(Ok, status);
1139
1140     GdipDeletePen(pen);
1141     GdipDeleteGraphics(graphics);
1142
1143     ReleaseDC(hwnd, hdc);
1144 }
1145
1146 static void test_GdipDrawCurveI(void)
1147 {
1148     GpStatus status;
1149     GpGraphics *graphics = NULL;
1150     GpPen *pen = NULL;
1151     HDC hdc = GetDC( hwnd );
1152     GpPoint points[3];
1153
1154     points[0].X = 0;
1155     points[0].Y = 0;
1156
1157     points[1].X = 40;
1158     points[1].Y = 20;
1159
1160     points[2].X = 10;
1161     points[2].Y = 40;
1162
1163     /* make a graphics object and pen object */
1164     ok(hdc != NULL, "Expected HDC to be initialized\n");
1165
1166     status = GdipCreateFromHDC(hdc, &graphics);
1167     expect(Ok, status);
1168     ok(graphics != NULL, "Expected graphics to be initialized\n");
1169
1170     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1171     expect(Ok, status);
1172     ok(pen != NULL, "Expected pen to be initialized\n");
1173
1174     /* InvalidParameter cases: null graphics, null pen */
1175     status = GdipDrawCurveI(NULL, NULL, points, 3);
1176     expect(InvalidParameter, status);
1177
1178     status = GdipDrawCurveI(graphics, NULL, points, 3);
1179     expect(InvalidParameter, status);
1180
1181     status = GdipDrawCurveI(NULL, pen, points, 3);
1182     expect(InvalidParameter, status);
1183
1184     /* InvalidParameter cases: invalid count */
1185     status = GdipDrawCurveI(graphics, pen, points, -1);
1186     expect(OutOfMemory, status);
1187
1188     status = GdipDrawCurveI(graphics, pen, points, 0);
1189     expect(InvalidParameter, status);
1190
1191     status = GdipDrawCurveI(graphics, pen, points, 1);
1192     expect(InvalidParameter, status);
1193
1194     /* Valid test cases */
1195     status = GdipDrawCurveI(graphics, pen, points, 2);
1196     expect(Ok, status);
1197
1198     status = GdipDrawCurveI(graphics, pen, points, 3);
1199     expect(Ok, status);
1200
1201     GdipDeletePen(pen);
1202     GdipDeleteGraphics(graphics);
1203
1204     ReleaseDC(hwnd, hdc);
1205 }
1206
1207 static void test_GdipDrawLineI(void)
1208 {
1209     GpStatus status;
1210     GpGraphics *graphics = NULL;
1211     GpPen *pen = NULL;
1212     HDC hdc = GetDC( hwnd );
1213
1214     /* make a graphics object and pen object */
1215     ok(hdc != NULL, "Expected HDC to be initialized\n");
1216
1217     status = GdipCreateFromHDC(hdc, &graphics);
1218     expect(Ok, status);
1219     ok(graphics != NULL, "Expected graphics to be initialized\n");
1220
1221     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1222     expect(Ok, status);
1223     ok(pen != NULL, "Expected pen to be initialized\n");
1224
1225     /* InvalidParameter cases: null graphics, null pen */
1226     status = GdipDrawLineI(NULL, NULL, 0, 0, 0, 0);
1227     expect(InvalidParameter, status);
1228
1229     status = GdipDrawLineI(graphics, NULL, 0, 0, 0, 0);
1230     expect(InvalidParameter, status);
1231
1232     status = GdipDrawLineI(NULL, pen, 0, 0, 0, 0);
1233     expect(InvalidParameter, status);
1234
1235     /* successful case */
1236     status = GdipDrawLineI(graphics, pen, 0, 0, 0, 0);
1237     expect(Ok, status);
1238
1239     GdipDeletePen(pen);
1240     GdipDeleteGraphics(graphics);
1241
1242     ReleaseDC(hwnd, hdc);
1243 }
1244
1245 static void test_GdipDrawImagePointsRect(void)
1246 {
1247     GpStatus status;
1248     GpGraphics *graphics = NULL;
1249     GpPointF ptf[4];
1250     GpBitmap *bm = NULL;
1251     BYTE rbmi[sizeof(BITMAPINFOHEADER)];
1252     BYTE buff[400];
1253     BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
1254     HDC hdc = GetDC( hwnd );
1255     if (!hdc)
1256         return;
1257
1258     memset(rbmi, 0, sizeof(rbmi));
1259     bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1260     bmi->bmiHeader.biWidth = 10;
1261     bmi->bmiHeader.biHeight = 10;
1262     bmi->bmiHeader.biPlanes = 1;
1263     bmi->bmiHeader.biBitCount = 32;
1264     bmi->bmiHeader.biCompression = BI_RGB;
1265     status = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
1266     expect(Ok, status);
1267     ok(NULL != bm, "Expected bitmap to be initialized\n");
1268     status = GdipCreateFromHDC(hdc, &graphics);
1269     expect(Ok, status);
1270     ptf[0].X = 0;
1271     ptf[0].Y = 0;
1272     ptf[1].X = 10;
1273     ptf[1].Y = 0;
1274     ptf[2].X = 0;
1275     ptf[2].Y = 10;
1276     ptf[3].X = 10;
1277     ptf[3].Y = 10;
1278     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 4, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1279     expect(NotImplemented, status);
1280     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 2, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1281     expect(InvalidParameter, status);
1282     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1283     expect(Ok, status);
1284     status = GdipDrawImagePointsRect(graphics, NULL, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1285     expect(InvalidParameter, status);
1286     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, NULL, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1287     expect(InvalidParameter, status);
1288     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 0, 0, UnitPixel, NULL, NULL, NULL);
1289     expect(Ok, status);
1290     memset(ptf, 0, sizeof(ptf));
1291     status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1292     expect(Ok, status);
1293
1294     GdipDisposeImage((GpImage*)bm);
1295     GdipDeleteGraphics(graphics);
1296     ReleaseDC(hwnd, hdc);
1297 }
1298
1299 static void test_GdipDrawLinesI(void)
1300 {
1301     GpStatus status;
1302     GpGraphics *graphics = NULL;
1303     GpPen *pen = NULL;
1304     GpPoint *ptf = NULL;
1305     HDC hdc = GetDC( hwnd );
1306
1307     /* make a graphics object and pen object */
1308     ok(hdc != NULL, "Expected HDC to be initialized\n");
1309
1310     status = GdipCreateFromHDC(hdc, &graphics);
1311     expect(Ok, status);
1312     ok(graphics != NULL, "Expected graphics to be initialized\n");
1313
1314     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1315     expect(Ok, status);
1316     ok(pen != NULL, "Expected pen to be initialized\n");
1317
1318     /* make some arbitrary valid points*/
1319     ptf = GdipAlloc(2 * sizeof(GpPointF));
1320
1321     ptf[0].X = 1;
1322     ptf[0].Y = 1;
1323
1324     ptf[1].X = 2;
1325     ptf[1].Y = 2;
1326
1327     /* InvalidParameter cases: null graphics, null pen, null points, count < 2*/
1328     status = GdipDrawLinesI(NULL, NULL, NULL, 0);
1329     expect(InvalidParameter, status);
1330
1331     status = GdipDrawLinesI(graphics, pen, ptf, 0);
1332     expect(InvalidParameter, status);
1333
1334     status = GdipDrawLinesI(graphics, NULL, ptf, 2);
1335     expect(InvalidParameter, status);
1336
1337     status = GdipDrawLinesI(NULL, pen, ptf, 2);
1338     expect(InvalidParameter, status);
1339
1340     /* successful case */
1341     status = GdipDrawLinesI(graphics, pen, ptf, 2);
1342     expect(Ok, status);
1343
1344     GdipFree(ptf);
1345     GdipDeletePen(pen);
1346     GdipDeleteGraphics(graphics);
1347
1348     ReleaseDC(hwnd, hdc);
1349 }
1350
1351 static void test_GdipFillClosedCurve(void)
1352 {
1353     GpStatus status;
1354     GpGraphics *graphics = NULL;
1355     GpSolidFill *brush = NULL;
1356     HDC hdc = GetDC( hwnd );
1357     GpPointF points[3];
1358
1359     points[0].X = 0;
1360     points[0].Y = 0;
1361
1362     points[1].X = 40;
1363     points[1].Y = 20;
1364
1365     points[2].X = 10;
1366     points[2].Y = 40;
1367
1368     /* make a graphics object and brush object */
1369     ok(hdc != NULL, "Expected HDC to be initialized\n");
1370
1371     status = GdipCreateFromHDC(hdc, &graphics);
1372     expect(Ok, status);
1373     ok(graphics != NULL, "Expected graphics to be initialized\n");
1374
1375     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1376
1377     /* InvalidParameter cases: null graphics, null brush, null points */
1378     status = GdipFillClosedCurve(NULL, NULL, NULL, 3);
1379     expect(InvalidParameter, status);
1380
1381     status = GdipFillClosedCurve(graphics, NULL, NULL, 3);
1382     expect(InvalidParameter, status);
1383
1384     status = GdipFillClosedCurve(NULL, (GpBrush*)brush, NULL, 3);
1385     expect(InvalidParameter, status);
1386
1387     status = GdipFillClosedCurve(NULL, NULL, points, 3);
1388     expect(InvalidParameter, status);
1389
1390     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, NULL, 3);
1391     expect(InvalidParameter, status);
1392
1393     status = GdipFillClosedCurve(graphics, NULL, points, 3);
1394     expect(InvalidParameter, status);
1395
1396     status = GdipFillClosedCurve(NULL, (GpBrush*)brush, points, 3);
1397     expect(InvalidParameter, status);
1398
1399     /* InvalidParameter cases: invalid count */
1400     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, -1);
1401     expect(InvalidParameter, status);
1402
1403     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 0);
1404     expect(InvalidParameter, status);
1405
1406     /* Valid test cases */
1407     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 1);
1408     expect(Ok, status);
1409
1410     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 2);
1411     expect(Ok, status);
1412
1413     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 3);
1414     expect(Ok, status);
1415
1416     GdipDeleteGraphics(graphics);
1417     GdipDeleteBrush((GpBrush*)brush);
1418
1419     ReleaseDC(hwnd, hdc);
1420 }
1421
1422 static void test_GdipFillClosedCurveI(void)
1423 {
1424     GpStatus status;
1425     GpGraphics *graphics = NULL;
1426     GpSolidFill *brush = NULL;
1427     HDC hdc = GetDC( hwnd );
1428     GpPoint points[3];
1429
1430     points[0].X = 0;
1431     points[0].Y = 0;
1432
1433     points[1].X = 40;
1434     points[1].Y = 20;
1435
1436     points[2].X = 10;
1437     points[2].Y = 40;
1438
1439     /* make a graphics object and brush object */
1440     ok(hdc != NULL, "Expected HDC to be initialized\n");
1441
1442     status = GdipCreateFromHDC(hdc, &graphics);
1443     expect(Ok, status);
1444     ok(graphics != NULL, "Expected graphics to be initialized\n");
1445
1446     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1447
1448     /* InvalidParameter cases: null graphics, null brush */
1449     /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
1450              when points == NULL, so don't test this condition */
1451     status = GdipFillClosedCurveI(NULL, NULL, points, 3);
1452     expect(InvalidParameter, status);
1453
1454     status = GdipFillClosedCurveI(graphics, NULL, points, 3);
1455     expect(InvalidParameter, status);
1456
1457     status = GdipFillClosedCurveI(NULL, (GpBrush*)brush, points, 3);
1458     expect(InvalidParameter, status);
1459
1460     /* InvalidParameter cases: invalid count */
1461     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 0);
1462     expect(InvalidParameter, status);
1463
1464     /* OutOfMemory cases: large (unsigned) int */
1465     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, -1);
1466     expect(OutOfMemory, status);
1467
1468     /* Valid test cases */
1469     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 1);
1470     expect(Ok, status);
1471
1472     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 2);
1473     expect(Ok, status);
1474
1475     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 3);
1476     expect(Ok, status);
1477
1478     GdipDeleteGraphics(graphics);
1479     GdipDeleteBrush((GpBrush*)brush);
1480
1481     ReleaseDC(hwnd, hdc);
1482 }
1483
1484 static void test_Get_Release_DC(void)
1485 {
1486     GpStatus status;
1487     GpGraphics *graphics = NULL;
1488     GpPen *pen;
1489     GpSolidFill *brush;
1490     GpPath *path;
1491     HDC hdc = GetDC( hwnd );
1492     HDC retdc;
1493     REAL r;
1494     CompositingQuality quality;
1495     CompositingMode compmode;
1496     InterpolationMode intmode;
1497     GpMatrix *m;
1498     GpRegion *region;
1499     GpUnit unit;
1500     PixelOffsetMode offsetmode;
1501     SmoothingMode smoothmode;
1502     TextRenderingHint texthint;
1503     GpPointF ptf[5];
1504     GpPoint  pt[5];
1505     GpRectF  rectf[2];
1506     GpRect   rect[2];
1507     GpRegion *clip;
1508     INT i;
1509     BOOL res;
1510     ARGB color = 0x00000000;
1511     HRGN hrgn = CreateRectRgn(0, 0, 10, 10);
1512
1513     pt[0].X = 10;
1514     pt[0].Y = 10;
1515     pt[1].X = 20;
1516     pt[1].Y = 15;
1517     pt[2].X = 40;
1518     pt[2].Y = 80;
1519     pt[3].X = -20;
1520     pt[3].Y = 20;
1521     pt[4].X = 50;
1522     pt[4].Y = 110;
1523
1524     for(i = 0; i < 5;i++){
1525         ptf[i].X = (REAL)pt[i].X;
1526         ptf[i].Y = (REAL)pt[i].Y;
1527     }
1528
1529     rect[0].X = 0;
1530     rect[0].Y = 0;
1531     rect[0].Width  = 50;
1532     rect[0].Height = 70;
1533     rect[1].X = 0;
1534     rect[1].Y = 0;
1535     rect[1].Width  = 10;
1536     rect[1].Height = 20;
1537
1538     for(i = 0; i < 2;i++){
1539         rectf[i].X = (REAL)rect[i].X;
1540         rectf[i].Y = (REAL)rect[i].Y;
1541         rectf[i].Height = (REAL)rect[i].Height;
1542         rectf[i].Width  = (REAL)rect[i].Width;
1543     }
1544
1545     status = GdipCreateMatrix(&m);
1546     expect(Ok, status);
1547     GdipCreateRegion(&region);
1548     GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1549     GdipCreatePath(FillModeAlternate, &path);
1550     GdipCreateRegion(&clip);
1551
1552     status = GdipCreateFromHDC(hdc, &graphics);
1553     expect(Ok, status);
1554     ok(graphics != NULL, "Expected graphics to be initialized\n");
1555     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1556     expect(Ok, status);
1557
1558     /* NULL arguments */
1559     status = GdipGetDC(NULL, NULL);
1560     expect(InvalidParameter, status);
1561     status = GdipGetDC(graphics, NULL);
1562     expect(InvalidParameter, status);
1563     status = GdipGetDC(NULL, &retdc);
1564     expect(InvalidParameter, status);
1565
1566     status = GdipReleaseDC(NULL, NULL);
1567     expect(InvalidParameter, status);
1568     status = GdipReleaseDC(graphics, NULL);
1569     expect(InvalidParameter, status);
1570     status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
1571     expect(InvalidParameter, status);
1572
1573     /* Release without Get */
1574     status = GdipReleaseDC(graphics, hdc);
1575     expect(InvalidParameter, status);
1576
1577     retdc = NULL;
1578     status = GdipGetDC(graphics, &retdc);
1579     expect(Ok, status);
1580     ok(retdc == hdc, "Invalid HDC returned\n");
1581     /* call it once more */
1582     status = GdipGetDC(graphics, &retdc);
1583     expect(ObjectBusy, status);
1584
1585     /* try all Graphics calls here */
1586     status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
1587     expect(ObjectBusy, status);
1588     status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
1589     expect(ObjectBusy, status);
1590     status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
1591     expect(ObjectBusy, status);
1592     status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
1593     expect(ObjectBusy, status);
1594     status = GdipDrawBeziers(graphics, pen, ptf, 5);
1595     expect(ObjectBusy, status);
1596     status = GdipDrawBeziersI(graphics, pen, pt, 5);
1597     expect(ObjectBusy, status);
1598     status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
1599     expect(ObjectBusy, status);
1600     status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
1601     expect(ObjectBusy, status);
1602     status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
1603     expect(ObjectBusy, status);
1604     status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
1605     expect(ObjectBusy, status);
1606     status = GdipDrawCurve(graphics, pen, ptf, 5);
1607     expect(ObjectBusy, status);
1608     status = GdipDrawCurveI(graphics, pen, pt, 5);
1609     expect(ObjectBusy, status);
1610     status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
1611     expect(ObjectBusy, status);
1612     status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
1613     expect(ObjectBusy, status);
1614     status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
1615     expect(ObjectBusy, status);
1616     status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
1617     expect(ObjectBusy, status);
1618     /* GdipDrawImage/GdipDrawImageI */
1619     /* GdipDrawImagePointsRect/GdipDrawImagePointsRectI */
1620     /* GdipDrawImageRectRect/GdipDrawImageRectRectI */
1621     /* GdipDrawImageRect/GdipDrawImageRectI */
1622     status = GdipDrawLine(graphics, pen, 0.0, 0.0, 100.0, 200.0);
1623     expect(ObjectBusy, status);
1624     status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
1625     expect(ObjectBusy, status);
1626     status = GdipDrawLines(graphics, pen, ptf, 5);
1627     expect(ObjectBusy, status);
1628     status = GdipDrawLinesI(graphics, pen, pt, 5);
1629     expect(ObjectBusy, status);
1630     status = GdipDrawPath(graphics, pen, path);
1631     expect(ObjectBusy, status);
1632     status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1633     expect(ObjectBusy, status);
1634     status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
1635     expect(ObjectBusy, status);
1636     status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
1637     expect(ObjectBusy, status);
1638     status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
1639     expect(ObjectBusy, status);
1640     status = GdipDrawRectangles(graphics, pen, rectf, 2);
1641     expect(ObjectBusy, status);
1642     status = GdipDrawRectanglesI(graphics, pen, rect, 2);
1643     expect(ObjectBusy, status);
1644     /* GdipDrawString */
1645     status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
1646     expect(ObjectBusy, status);
1647     status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
1648     expect(ObjectBusy, status);
1649     status = GdipFillClosedCurve(graphics, (GpBrush*)brush, ptf, 5);
1650     expect(ObjectBusy, status);
1651     status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, pt, 5);
1652     expect(ObjectBusy, status);
1653     status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1654     expect(ObjectBusy, status);
1655     status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1656     expect(ObjectBusy, status);
1657     status = GdipFillPath(graphics, (GpBrush*)brush, path);
1658     expect(ObjectBusy, status);
1659     status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
1660     expect(ObjectBusy, status);
1661     status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
1662     expect(ObjectBusy, status);
1663     status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
1664     expect(ObjectBusy, status);
1665     status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
1666     expect(ObjectBusy, status);
1667     status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
1668     expect(ObjectBusy, status);
1669     status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
1670     expect(ObjectBusy, status);
1671     status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1672     expect(ObjectBusy, status);
1673     status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1674     expect(ObjectBusy, status);
1675     status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
1676     expect(ObjectBusy, status);
1677     status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
1678     expect(ObjectBusy, status);
1679     status = GdipFillRegion(graphics, (GpBrush*)brush, region);
1680     expect(ObjectBusy, status);
1681     status = GdipFlush(graphics, FlushIntentionFlush);
1682     expect(ObjectBusy, status);
1683     status = GdipGetClipBounds(graphics, rectf);
1684     expect(ObjectBusy, status);
1685     status = GdipGetClipBoundsI(graphics, rect);
1686     expect(ObjectBusy, status);
1687     status = GdipGetCompositingMode(graphics, &compmode);
1688     expect(ObjectBusy, status);
1689     status = GdipGetCompositingQuality(graphics, &quality);
1690     expect(ObjectBusy, status);
1691     status = GdipGetInterpolationMode(graphics, &intmode);
1692     expect(ObjectBusy, status);
1693     status = GdipGetNearestColor(graphics, &color);
1694     expect(ObjectBusy, status);
1695     status = GdipGetPageScale(graphics, &r);
1696     expect(ObjectBusy, status);
1697     status = GdipGetPageUnit(graphics, &unit);
1698     expect(ObjectBusy, status);
1699     status = GdipGetPixelOffsetMode(graphics, &offsetmode);
1700     expect(ObjectBusy, status);
1701     status = GdipGetSmoothingMode(graphics, &smoothmode);
1702     expect(ObjectBusy, status);
1703     status = GdipGetTextRenderingHint(graphics, &texthint);
1704     expect(ObjectBusy, status);
1705     status = GdipGetWorldTransform(graphics, m);
1706     expect(ObjectBusy, status);
1707     status = GdipGraphicsClear(graphics, 0xdeadbeef);
1708     expect(ObjectBusy, status);
1709     status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
1710     expect(ObjectBusy, status);
1711     status = GdipIsVisiblePointI(graphics, 0, 0, &res);
1712     expect(ObjectBusy, status);
1713     /* GdipMeasureCharacterRanges */
1714     /* GdipMeasureString */
1715     status = GdipResetClip(graphics);
1716     expect(ObjectBusy, status);
1717     status = GdipResetWorldTransform(graphics);
1718     expect(ObjectBusy, status);
1719     /* GdipRestoreGraphics */
1720     status = GdipRotateWorldTransform(graphics, 15.0, MatrixOrderPrepend);
1721     expect(ObjectBusy, status);
1722     /*  GdipSaveGraphics */
1723     status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
1724     expect(ObjectBusy, status);
1725     status = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
1726     expect(ObjectBusy, status);
1727     status = GdipSetCompositingQuality(graphics, CompositingQualityDefault);
1728     expect(ObjectBusy, status);
1729     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
1730     expect(ObjectBusy, status);
1731     status = GdipSetPageScale(graphics, 1.0);
1732     expect(ObjectBusy, status);
1733     status = GdipSetPageUnit(graphics, UnitWorld);
1734     expect(ObjectBusy, status);
1735     status = GdipSetPixelOffsetMode(graphics, PixelOffsetModeDefault);
1736     expect(ObjectBusy, status);
1737     status = GdipSetSmoothingMode(graphics, SmoothingModeDefault);
1738     expect(ObjectBusy, status);
1739     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
1740     expect(ObjectBusy, status);
1741     status = GdipSetWorldTransform(graphics, m);
1742     expect(ObjectBusy, status);
1743     status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
1744     expect(ObjectBusy, status);
1745     status = GdipSetClipHrgn(graphics, hrgn, CombineModeReplace);
1746     expect(ObjectBusy, status);
1747     status = GdipSetClipPath(graphics, path, CombineModeReplace);
1748     expect(ObjectBusy, status);
1749     status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
1750     expect(ObjectBusy, status);
1751     status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
1752     expect(ObjectBusy, status);
1753     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1754     expect(ObjectBusy, status);
1755     status = GdipTranslateClip(graphics, 0.0, 0.0);
1756     expect(ObjectBusy, status);
1757     status = GdipTranslateClipI(graphics, 0, 0);
1758     expect(ObjectBusy, status);
1759     status = GdipDrawPolygon(graphics, pen, ptf, 5);
1760     expect(ObjectBusy, status);
1761     status = GdipDrawPolygonI(graphics, pen, pt, 5);
1762     expect(ObjectBusy, status);
1763     status = GdipGetDpiX(graphics, &r);
1764     expect(ObjectBusy, status);
1765     status = GdipGetDpiY(graphics, &r);
1766     expect(ObjectBusy, status);
1767     status = GdipMultiplyWorldTransform(graphics, m, MatrixOrderPrepend);
1768     expect(ObjectBusy, status);
1769     status = GdipGetClip(graphics, region);
1770     expect(ObjectBusy, status);
1771     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 5);
1772     expect(ObjectBusy, status);
1773
1774     /* try to delete before release */
1775     status = GdipDeleteGraphics(graphics);
1776     expect(ObjectBusy, status);
1777
1778     status = GdipReleaseDC(graphics, retdc);
1779     expect(Ok, status);
1780
1781     GdipDeletePen(pen);
1782     GdipDeleteGraphics(graphics);
1783
1784     GdipDeleteRegion(clip);
1785     GdipDeletePath(path);
1786     GdipDeleteBrush((GpBrush*)brush);
1787     GdipDeleteRegion(region);
1788     GdipDeleteMatrix(m);
1789     DeleteObject(hrgn);
1790
1791     ReleaseDC(hwnd, hdc);
1792 }
1793
1794 static void test_transformpoints(void)
1795 {
1796     GpStatus status;
1797     GpGraphics *graphics = NULL;
1798     HDC hdc = GetDC( hwnd );
1799     GpPointF ptf[2];
1800     GpPoint pt[2];
1801
1802     status = GdipCreateFromHDC(hdc, &graphics);
1803     expect(Ok, status);
1804
1805     /* NULL arguments */
1806     status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1807     expect(InvalidParameter, status);
1808     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1809     expect(InvalidParameter, status);
1810     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 0);
1811     expect(InvalidParameter, status);
1812     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1);
1813     expect(InvalidParameter, status);
1814
1815     ptf[0].X = 1.0;
1816     ptf[0].Y = 0.0;
1817     ptf[1].X = 0.0;
1818     ptf[1].Y = 1.0;
1819     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1820     expect(Ok, status);
1821     expectf(1.0, ptf[0].X);
1822     expectf(0.0, ptf[0].Y);
1823     expectf(0.0, ptf[1].X);
1824     expectf(1.0, ptf[1].Y);
1825
1826     status = GdipTranslateWorldTransform(graphics, 5.0, 5.0, MatrixOrderAppend);
1827     expect(Ok, status);
1828     status = GdipSetPageUnit(graphics, UnitPixel);
1829     expect(Ok, status);
1830     status = GdipSetPageScale(graphics, 3.0);
1831     expect(Ok, status);
1832
1833     ptf[0].X = 1.0;
1834     ptf[0].Y = 0.0;
1835     ptf[1].X = 0.0;
1836     ptf[1].Y = 1.0;
1837     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1838     expect(Ok, status);
1839     expectf(18.0, ptf[0].X);
1840     expectf(15.0, ptf[0].Y);
1841     expectf(15.0, ptf[1].X);
1842     expectf(18.0, ptf[1].Y);
1843
1844     ptf[0].X = 1.0;
1845     ptf[0].Y = 0.0;
1846     ptf[1].X = 0.0;
1847     ptf[1].Y = 1.0;
1848     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 2);
1849     expect(Ok, status);
1850     expectf(6.0, ptf[0].X);
1851     expectf(5.0, ptf[0].Y);
1852     expectf(5.0, ptf[1].X);
1853     expectf(6.0, ptf[1].Y);
1854
1855     ptf[0].X = 1.0;
1856     ptf[0].Y = 0.0;
1857     ptf[1].X = 0.0;
1858     ptf[1].Y = 1.0;
1859     status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpacePage, ptf, 2);
1860     expect(Ok, status);
1861     expectf(3.0, ptf[0].X);
1862     expectf(0.0, ptf[0].Y);
1863     expectf(0.0, ptf[1].X);
1864     expectf(3.0, ptf[1].Y);
1865
1866     ptf[0].X = 18.0;
1867     ptf[0].Y = 15.0;
1868     ptf[1].X = 15.0;
1869     ptf[1].Y = 18.0;
1870     status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
1871     expect(Ok, status);
1872     expectf(1.0, ptf[0].X);
1873     expectf(0.0, ptf[0].Y);
1874     expectf(0.0, ptf[1].X);
1875     expectf(1.0, ptf[1].Y);
1876
1877     ptf[0].X = 6.0;
1878     ptf[0].Y = 5.0;
1879     ptf[1].X = 5.0;
1880     ptf[1].Y = 6.0;
1881     status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpacePage, ptf, 2);
1882     expect(Ok, status);
1883     expectf(1.0, ptf[0].X);
1884     expectf(0.0, ptf[0].Y);
1885     expectf(0.0, ptf[1].X);
1886     expectf(1.0, ptf[1].Y);
1887
1888     ptf[0].X = 3.0;
1889     ptf[0].Y = 0.0;
1890     ptf[1].X = 0.0;
1891     ptf[1].Y = 3.0;
1892     status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceDevice, ptf, 2);
1893     expect(Ok, status);
1894     expectf(1.0, ptf[0].X);
1895     expectf(0.0, ptf[0].Y);
1896     expectf(0.0, ptf[1].X);
1897     expectf(1.0, ptf[1].Y);
1898
1899     pt[0].X = 1;
1900     pt[0].Y = 0;
1901     pt[1].X = 0;
1902     pt[1].Y = 1;
1903     status = GdipTransformPointsI(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 2);
1904     expect(Ok, status);
1905     expect(18, pt[0].X);
1906     expect(15, pt[0].Y);
1907     expect(15, pt[1].X);
1908     expect(18, pt[1].Y);
1909
1910     GdipDeleteGraphics(graphics);
1911     ReleaseDC(hwnd, hdc);
1912 }
1913
1914 static void test_get_set_clip(void)
1915 {
1916     GpStatus status;
1917     GpGraphics *graphics = NULL;
1918     HDC hdc = GetDC( hwnd );
1919     GpRegion *clip;
1920     GpRectF rect;
1921     BOOL res;
1922
1923     status = GdipCreateFromHDC(hdc, &graphics);
1924     expect(Ok, status);
1925
1926     rect.X = rect.Y = 0.0;
1927     rect.Height = rect.Width = 100.0;
1928
1929     status = GdipCreateRegionRect(&rect, &clip);
1930     expect(Ok, status);
1931
1932     /* NULL arguments */
1933     status = GdipGetClip(NULL, NULL);
1934     expect(InvalidParameter, status);
1935     status = GdipGetClip(graphics, NULL);
1936     expect(InvalidParameter, status);
1937     status = GdipGetClip(NULL, clip);
1938     expect(InvalidParameter, status);
1939
1940     status = GdipSetClipRegion(NULL, NULL, CombineModeReplace);
1941     expect(InvalidParameter, status);
1942     status = GdipSetClipRegion(graphics, NULL, CombineModeReplace);
1943     expect(InvalidParameter, status);
1944
1945     status = GdipSetClipPath(NULL, NULL, CombineModeReplace);
1946     expect(InvalidParameter, status);
1947     status = GdipSetClipPath(graphics, NULL, CombineModeReplace);
1948     expect(InvalidParameter, status);
1949
1950     res = FALSE;
1951     status = GdipGetClip(graphics, clip);
1952     expect(Ok, status);
1953     status = GdipIsInfiniteRegion(clip, graphics, &res);
1954     expect(Ok, status);
1955     expect(TRUE, res);
1956
1957     /* remains infinite after reset */
1958     res = FALSE;
1959     status = GdipResetClip(graphics);
1960     expect(Ok, status);
1961     status = GdipGetClip(graphics, clip);
1962     expect(Ok, status);
1963     status = GdipIsInfiniteRegion(clip, graphics, &res);
1964     expect(Ok, status);
1965     expect(TRUE, res);
1966
1967     /* set to empty and then reset to infinite */
1968     status = GdipSetEmpty(clip);
1969     expect(Ok, status);
1970     status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1971     expect(Ok, status);
1972
1973     status = GdipGetClip(graphics, clip);
1974     expect(Ok, status);
1975     res = FALSE;
1976     status = GdipIsEmptyRegion(clip, graphics, &res);
1977     expect(Ok, status);
1978     expect(TRUE, res);
1979     status = GdipResetClip(graphics);
1980     expect(Ok, status);
1981     status = GdipGetClip(graphics, clip);
1982     expect(Ok, status);
1983     res = FALSE;
1984     status = GdipIsInfiniteRegion(clip, graphics, &res);
1985     expect(Ok, status);
1986     expect(TRUE, res);
1987
1988     GdipDeleteRegion(clip);
1989
1990     GdipDeleteGraphics(graphics);
1991     ReleaseDC(hwnd, hdc);
1992 }
1993
1994 static void test_isempty(void)
1995 {
1996     GpStatus status;
1997     GpGraphics *graphics = NULL;
1998     HDC hdc = GetDC( hwnd );
1999     GpRegion *clip;
2000     BOOL res;
2001
2002     status = GdipCreateFromHDC(hdc, &graphics);
2003     expect(Ok, status);
2004
2005     status = GdipCreateRegion(&clip);
2006     expect(Ok, status);
2007
2008     /* NULL */
2009     status = GdipIsClipEmpty(NULL, NULL);
2010     expect(InvalidParameter, status);
2011     status = GdipIsClipEmpty(graphics, NULL);
2012     expect(InvalidParameter, status);
2013     status = GdipIsClipEmpty(NULL, &res);
2014     expect(InvalidParameter, status);
2015
2016     /* default is infinite */
2017     res = TRUE;
2018     status = GdipIsClipEmpty(graphics, &res);
2019     expect(Ok, status);
2020     expect(FALSE, res);
2021
2022     GdipDeleteRegion(clip);
2023
2024     GdipDeleteGraphics(graphics);
2025     ReleaseDC(hwnd, hdc);
2026 }
2027
2028 static void test_clear(void)
2029 {
2030     GpStatus status;
2031
2032     status = GdipGraphicsClear(NULL, 0xdeadbeef);
2033     expect(InvalidParameter, status);
2034 }
2035
2036 static void test_textcontrast(void)
2037 {
2038     GpStatus status;
2039     HDC hdc = GetDC( hwnd );
2040     GpGraphics *graphics;
2041     UINT contrast;
2042
2043     status = GdipGetTextContrast(NULL, NULL);
2044     expect(InvalidParameter, status);
2045
2046     status = GdipCreateFromHDC(hdc, &graphics);
2047     expect(Ok, status);
2048
2049     status = GdipGetTextContrast(graphics, NULL);
2050     expect(InvalidParameter, status);
2051     status = GdipGetTextContrast(graphics, &contrast);
2052     expect(Ok, status);
2053     expect(4, contrast);
2054
2055     GdipDeleteGraphics(graphics);
2056     ReleaseDC(hwnd, hdc);
2057 }
2058
2059 static void test_GdipDrawString(void)
2060 {
2061     GpStatus status;
2062     GpGraphics *graphics = NULL;
2063     GpFont *fnt = NULL;
2064     RectF  rect;
2065     GpStringFormat *format;
2066     GpBrush *brush;
2067     LOGFONTA logfont;
2068     HDC hdc = GetDC( hwnd );
2069     static const WCHAR string[] = {'T','e','s','t',0};
2070     static const PointF positions[4] = {{0,0}, {1,1}, {2,2}, {3,3}};
2071     GpMatrix *matrix;
2072
2073     memset(&logfont,0,sizeof(logfont));
2074     strcpy(logfont.lfFaceName,"Arial");
2075     logfont.lfHeight = 12;
2076     logfont.lfCharSet = DEFAULT_CHARSET;
2077
2078     status = GdipCreateFromHDC(hdc, &graphics);
2079     expect(Ok, status);
2080
2081     status = GdipCreateFontFromLogfontA(hdc, &logfont, &fnt);
2082     if (status == NotTrueTypeFont || status == FileNotFound)
2083     {
2084         skip("Arial not installed.\n");
2085         return;
2086     }
2087     expect(Ok, status);
2088
2089     status = GdipCreateSolidFill((ARGB)0xdeadbeef, (GpSolidFill**)&brush);
2090     expect(Ok, status);
2091
2092     status = GdipCreateStringFormat(0,0,&format);
2093     expect(Ok, status);
2094
2095     rect.X = 0;
2096     rect.Y = 0;
2097     rect.Width = 0;
2098     rect.Height = 12;
2099
2100     status = GdipDrawString(graphics, string, 4, fnt, &rect, format, brush);
2101     expect(Ok, status);
2102
2103     status = GdipCreateMatrix(&matrix);
2104     expect(Ok, status);
2105
2106     status = GdipDrawDriverString(NULL, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2107     expect(InvalidParameter, status);
2108
2109     status = GdipDrawDriverString(graphics, NULL, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2110     expect(InvalidParameter, status);
2111
2112     status = GdipDrawDriverString(graphics, string, 4, NULL, brush, positions, DriverStringOptionsCmapLookup, matrix);
2113     expect(InvalidParameter, status);
2114
2115     status = GdipDrawDriverString(graphics, string, 4, fnt, NULL, positions, DriverStringOptionsCmapLookup, matrix);
2116     expect(InvalidParameter, status);
2117
2118     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, NULL, DriverStringOptionsCmapLookup, matrix);
2119     expect(InvalidParameter, status);
2120
2121     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup|0x10, matrix);
2122     expect(Ok, status);
2123
2124     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, NULL);
2125     expect(Ok, status);
2126
2127     status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2128     expect(Ok, status);
2129
2130     GdipDeleteMatrix(matrix);
2131     GdipDeleteGraphics(graphics);
2132     GdipDeleteBrush(brush);
2133     GdipDeleteFont(fnt);
2134     GdipDeleteStringFormat(format);
2135
2136     ReleaseDC(hwnd, hdc);
2137 }
2138
2139 static void test_GdipGetVisibleClipBounds_screen(void)
2140 {
2141     GpStatus status;
2142     GpGraphics *graphics = NULL;
2143     HDC hdc = GetDC(0);
2144     GpRectF rectf, exp, clipr;
2145     GpRect recti;
2146
2147     ok(hdc != NULL, "Expected HDC to be initialized\n");
2148
2149     status = GdipCreateFromHDC(hdc, &graphics);
2150     expect(Ok, status);
2151     ok(graphics != NULL, "Expected graphics to be initialized\n");
2152
2153     /* no clipping rect */
2154     exp.X = 0;
2155     exp.Y = 0;
2156     exp.Width = GetDeviceCaps(hdc, HORZRES);
2157     exp.Height = GetDeviceCaps(hdc, VERTRES);
2158
2159     status = GdipGetVisibleClipBounds(graphics, &rectf);
2160     expect(Ok, status);
2161     ok(rectf.X == exp.X &&
2162         rectf.Y == exp.Y &&
2163         rectf.Width == exp.Width &&
2164         rectf.Height == exp.Height,
2165         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2166         "the screen (%0.f, %0.f, %0.f, %0.f)\n",
2167         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2168         exp.X, exp.Y, exp.Width, exp.Height);
2169
2170     /* clipping rect entirely within window */
2171     exp.X = clipr.X = 10;
2172     exp.Y = clipr.Y = 12;
2173     exp.Width = clipr.Width = 14;
2174     exp.Height = clipr.Height = 16;
2175
2176     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2177     expect(Ok, status);
2178
2179     status = GdipGetVisibleClipBounds(graphics, &rectf);
2180     expect(Ok, status);
2181     ok(rectf.X == exp.X &&
2182         rectf.Y == exp.Y &&
2183         rectf.Width == exp.Width &&
2184         rectf.Height == exp.Height,
2185         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2186         "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2187         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2188         exp.X, exp.Y, exp.Width, exp.Height);
2189
2190     /* clipping rect partially outside of screen */
2191     clipr.X = -10;
2192     clipr.Y = -12;
2193     clipr.Width = 20;
2194     clipr.Height = 24;
2195
2196     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2197     expect(Ok, status);
2198
2199     exp.X = 0;
2200     exp.Y = 0;
2201     exp.Width = 10;
2202     exp.Height = 12;
2203
2204     status = GdipGetVisibleClipBounds(graphics, &rectf);
2205     expect(Ok, status);
2206     ok(rectf.X == exp.X &&
2207         rectf.Y == exp.Y &&
2208         rectf.Width == exp.Width &&
2209         rectf.Height == exp.Height,
2210         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2211         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2212         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2213         exp.X, exp.Y, exp.Width, exp.Height);
2214
2215     status = GdipGetVisibleClipBoundsI(graphics, &recti);
2216     expect(Ok, status);
2217     ok(recti.X == exp.X &&
2218         recti.Y == exp.Y &&
2219         recti.Width == exp.Width &&
2220         recti.Height == exp.Height,
2221         "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2222         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2223         recti.X, recti.Y, recti.Width, recti.Height,
2224         exp.X, exp.Y, exp.Width, exp.Height);
2225
2226     GdipDeleteGraphics(graphics);
2227     ReleaseDC(0, hdc);
2228 }
2229
2230 static void test_GdipGetVisibleClipBounds_window(void)
2231 {
2232     GpStatus status;
2233     GpGraphics *graphics = NULL;
2234     GpRectF rectf, window, exp, clipr;
2235     GpRect recti;
2236     HDC hdc;
2237     PAINTSTRUCT ps;
2238     RECT wnd_rect;
2239
2240     /* get client area size */
2241     ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n");
2242     window.X = wnd_rect.left;
2243     window.Y = wnd_rect.top;
2244     window.Width = wnd_rect.right - wnd_rect.left;
2245     window.Height = wnd_rect.bottom - wnd_rect.top;
2246
2247     hdc = BeginPaint(hwnd, &ps);
2248
2249     status = GdipCreateFromHDC(hdc, &graphics);
2250     expect(Ok, status);
2251     ok(graphics != NULL, "Expected graphics to be initialized\n");
2252
2253     status = GdipGetVisibleClipBounds(graphics, &rectf);
2254     expect(Ok, status);
2255     ok(rectf.X == window.X &&
2256         rectf.Y == window.Y &&
2257         rectf.Width == window.Width &&
2258         rectf.Height == window.Height,
2259         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2260         "the window (%0.f, %0.f, %0.f, %0.f)\n",
2261         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2262         window.X, window.Y, window.Width, window.Height);
2263
2264     /* clipping rect entirely within window */
2265     exp.X = clipr.X = 20;
2266     exp.Y = clipr.Y = 8;
2267     exp.Width = clipr.Width = 30;
2268     exp.Height = clipr.Height = 20;
2269
2270     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2271     expect(Ok, status);
2272
2273     status = GdipGetVisibleClipBounds(graphics, &rectf);
2274     expect(Ok, status);
2275     ok(rectf.X == exp.X &&
2276         rectf.Y == exp.Y &&
2277         rectf.Width == exp.Width &&
2278         rectf.Height == exp.Height,
2279         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2280         "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2281         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2282         exp.X, exp.Y, exp.Width, exp.Height);
2283
2284     /* clipping rect partially outside of window */
2285     clipr.X = window.Width - 10;
2286     clipr.Y = window.Height - 15;
2287     clipr.Width = 20;
2288     clipr.Height = 30;
2289
2290     status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2291     expect(Ok, status);
2292
2293     exp.X = window.Width - 10;
2294     exp.Y = window.Height - 15;
2295     exp.Width = 10;
2296     exp.Height = 15;
2297
2298     status = GdipGetVisibleClipBounds(graphics, &rectf);
2299     expect(Ok, status);
2300     ok(rectf.X == exp.X &&
2301         rectf.Y == exp.Y &&
2302         rectf.Width == exp.Width &&
2303         rectf.Height == exp.Height,
2304         "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2305         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2306         rectf.X, rectf.Y, rectf.Width, rectf.Height,
2307         exp.X, exp.Y, exp.Width, exp.Height);
2308
2309     status = GdipGetVisibleClipBoundsI(graphics, &recti);
2310     expect(Ok, status);
2311     ok(recti.X == exp.X &&
2312         recti.Y == exp.Y &&
2313         recti.Width == exp.Width &&
2314         recti.Height == exp.Height,
2315         "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2316         "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2317         recti.X, recti.Y, recti.Width, recti.Height,
2318         exp.X, exp.Y, exp.Width, exp.Height);
2319
2320     GdipDeleteGraphics(graphics);
2321     EndPaint(hwnd, &ps);
2322 }
2323
2324 static void test_GdipGetVisibleClipBounds(void)
2325 {
2326     GpGraphics* graphics = NULL;
2327     GpRectF rectf;
2328     GpRect rect;
2329     HDC hdc = GetDC( hwnd );
2330     GpStatus status;
2331
2332     status = GdipCreateFromHDC(hdc, &graphics);
2333     expect(Ok, status);
2334     ok(graphics != NULL, "Expected graphics to be initialized\n");
2335
2336     /* test null parameters */
2337     status = GdipGetVisibleClipBounds(graphics, NULL);
2338     expect(InvalidParameter, status);
2339
2340     status = GdipGetVisibleClipBounds(NULL, &rectf);
2341     expect(InvalidParameter, status);
2342
2343     status = GdipGetVisibleClipBoundsI(graphics, NULL);
2344     expect(InvalidParameter, status);
2345
2346     status = GdipGetVisibleClipBoundsI(NULL, &rect);
2347     expect(InvalidParameter, status);
2348
2349     GdipDeleteGraphics(graphics);
2350     ReleaseDC(hwnd, hdc);
2351
2352     test_GdipGetVisibleClipBounds_screen();
2353     test_GdipGetVisibleClipBounds_window();
2354 }
2355
2356 static void test_fromMemoryBitmap(void)
2357 {
2358     GpStatus status;
2359     GpGraphics *graphics = NULL;
2360     GpBitmap *bitmap = NULL;
2361     BYTE bits[48] = {0};
2362     HDC hdc=NULL;
2363     COLORREF color;
2364
2365     status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, bits, &bitmap);
2366     expect(Ok, status);
2367
2368     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2369     expect(Ok, status);
2370
2371     status = GdipGraphicsClear(graphics, 0xff686868);
2372     expect(Ok, status);
2373
2374     GdipDeleteGraphics(graphics);
2375
2376     /* drawing writes to the memory provided */
2377     expect(0x68, bits[10]);
2378
2379     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2380     expect(Ok, status);
2381
2382     status = GdipGetDC(graphics, &hdc);
2383     expect(Ok, status);
2384     ok(hdc != NULL, "got NULL hdc\n");
2385
2386     color = GetPixel(hdc, 0, 0);
2387     /* The HDC is write-only, and native fills with a solid color to figure out
2388      * which pixels have changed. */
2389     todo_wine expect(0x0c0b0d, color);
2390
2391     SetPixel(hdc, 0, 0, 0x797979);
2392     SetPixel(hdc, 1, 0, 0x0c0b0d);
2393
2394     status = GdipReleaseDC(graphics, hdc);
2395     expect(Ok, status);
2396
2397     GdipDeleteGraphics(graphics);
2398
2399     expect(0x79, bits[0]);
2400     todo_wine expect(0x68, bits[3]);
2401
2402     GdipDisposeImage((GpImage*)bitmap);
2403
2404     /* We get the same kind of write-only HDC for a "normal" bitmap */
2405     status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, NULL, &bitmap);
2406     expect(Ok, status);
2407
2408     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2409     expect(Ok, status);
2410
2411     status = GdipGetDC(graphics, &hdc);
2412     expect(Ok, status);
2413     ok(hdc != NULL, "got NULL hdc\n");
2414
2415     color = GetPixel(hdc, 0, 0);
2416     todo_wine expect(0x0c0b0d, color);
2417
2418     status = GdipReleaseDC(graphics, hdc);
2419     expect(Ok, status);
2420
2421     GdipDeleteGraphics(graphics);
2422
2423     GdipDisposeImage((GpImage*)bitmap);
2424 }
2425
2426 static void test_GdipIsVisiblePoint(void)
2427 {
2428     GpStatus status;
2429     GpGraphics *graphics = NULL;
2430     HDC hdc = GetDC( hwnd );
2431     REAL x, y;
2432     BOOL val;
2433
2434     ok(hdc != NULL, "Expected HDC to be initialized\n");
2435
2436     status = GdipCreateFromHDC(hdc, &graphics);
2437     expect(Ok, status);
2438     ok(graphics != NULL, "Expected graphics to be initialized\n");
2439
2440     /* null parameters */
2441     status = GdipIsVisiblePoint(NULL, 0, 0, &val);
2442     expect(InvalidParameter, status);
2443
2444     status = GdipIsVisiblePoint(graphics, 0, 0, NULL);
2445     expect(InvalidParameter, status);
2446
2447     status = GdipIsVisiblePointI(NULL, 0, 0, &val);
2448     expect(InvalidParameter, status);
2449
2450     status = GdipIsVisiblePointI(graphics, 0, 0, NULL);
2451     expect(InvalidParameter, status);
2452
2453     x = 0;
2454     y = 0;
2455     status = GdipIsVisiblePoint(graphics, x, y, &val);
2456     expect(Ok, status);
2457     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2458
2459     x = -10;
2460     y = 0;
2461     status = GdipIsVisiblePoint(graphics, x, y, &val);
2462     expect(Ok, status);
2463     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2464
2465     x = 0;
2466     y = -5;
2467     status = GdipIsVisiblePoint(graphics, x, y, &val);
2468     expect(Ok, status);
2469     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2470
2471     x = 1;
2472     y = 1;
2473     status = GdipIsVisiblePoint(graphics, x, y, &val);
2474     expect(Ok, status);
2475     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2476
2477     status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2478     expect(Ok, status);
2479
2480     x = 1;
2481     y = 1;
2482     status = GdipIsVisiblePoint(graphics, x, y, &val);
2483     expect(Ok, status);
2484     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2485
2486     x = 15.5;
2487     y = 40.5;
2488     status = GdipIsVisiblePoint(graphics, x, y, &val);
2489     expect(Ok, status);
2490     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2491
2492     /* translate into the center of the rect */
2493     GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2494
2495     x = 0;
2496     y = 0;
2497     status = GdipIsVisiblePoint(graphics, x, y, &val);
2498     expect(Ok, status);
2499     ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2500
2501     x = 25;
2502     y = 40;
2503     status = GdipIsVisiblePoint(graphics, x, y, &val);
2504     expect(Ok, status);
2505     ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2506
2507     GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2508
2509     /* corner cases */
2510     x = 9;
2511     y = 19;
2512     status = GdipIsVisiblePoint(graphics, x, y, &val);
2513     expect(Ok, status);
2514     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2515
2516     x = 9.25;
2517     y = 19.25;
2518     status = GdipIsVisiblePoint(graphics, x, y, &val);
2519     expect(Ok, status);
2520     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2521
2522     x = 9.5;
2523     y = 19.5;
2524     status = GdipIsVisiblePoint(graphics, x, y, &val);
2525     expect(Ok, status);
2526     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2527
2528     x = 9.75;
2529     y = 19.75;
2530     status = GdipIsVisiblePoint(graphics, x, y, &val);
2531     expect(Ok, status);
2532     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2533
2534     x = 10;
2535     y = 20;
2536     status = GdipIsVisiblePoint(graphics, x, y, &val);
2537     expect(Ok, status);
2538     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2539
2540     x = 40;
2541     y = 20;
2542     status = GdipIsVisiblePoint(graphics, x, y, &val);
2543     expect(Ok, status);
2544     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2545
2546     x = 39;
2547     y = 59;
2548     status = GdipIsVisiblePoint(graphics, x, y, &val);
2549     expect(Ok, status);
2550     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2551
2552     x = 39.25;
2553     y = 59.25;
2554     status = GdipIsVisiblePoint(graphics, x, y, &val);
2555     expect(Ok, status);
2556     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2557
2558     x = 39.5;
2559     y = 39.5;
2560     status = GdipIsVisiblePoint(graphics, x, y, &val);
2561     expect(Ok, status);
2562     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2563
2564     x = 39.75;
2565     y = 59.75;
2566     status = GdipIsVisiblePoint(graphics, x, y, &val);
2567     expect(Ok, status);
2568     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2569
2570     x = 40;
2571     y = 60;
2572     status = GdipIsVisiblePoint(graphics, x, y, &val);
2573     expect(Ok, status);
2574     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2575
2576     x = 40.15;
2577     y = 60.15;
2578     status = GdipIsVisiblePoint(graphics, x, y, &val);
2579     expect(Ok, status);
2580     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2581
2582     x = 10;
2583     y = 60;
2584     status = GdipIsVisiblePoint(graphics, x, y, &val);
2585     expect(Ok, status);
2586     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2587
2588     /* integer version */
2589     x = 25;
2590     y = 30;
2591     status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2592     expect(Ok, status);
2593     ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2594
2595     x = 50;
2596     y = 100;
2597     status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2598     expect(Ok, status);
2599     ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2600
2601     GdipDeleteGraphics(graphics);
2602     ReleaseDC(hwnd, hdc);
2603 }
2604
2605 static void test_GdipIsVisibleRect(void)
2606 {
2607     GpStatus status;
2608     GpGraphics *graphics = NULL;
2609     HDC hdc = GetDC( hwnd );
2610     REAL x, y, width, height;
2611     BOOL val;
2612
2613     ok(hdc != NULL, "Expected HDC to be initialized\n");
2614
2615     status = GdipCreateFromHDC(hdc, &graphics);
2616     expect(Ok, status);
2617     ok(graphics != NULL, "Expected graphics to be initialized\n");
2618
2619     status = GdipIsVisibleRect(NULL, 0, 0, 0, 0, &val);
2620     expect(InvalidParameter, status);
2621
2622     status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL);
2623     expect(InvalidParameter, status);
2624
2625     status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val);
2626     expect(InvalidParameter, status);
2627
2628     status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL);
2629     expect(InvalidParameter, status);
2630
2631     /* entirely within the visible region */
2632     x = 0; width = 10;
2633     y = 0; height = 10;
2634     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2635     expect(Ok, status);
2636     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2637
2638     /* partially outside */
2639     x = -10; width = 20;
2640     y = -10; height = 20;
2641     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2642     expect(Ok, status);
2643     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2644
2645     /* entirely outside */
2646     x = -10; width = 5;
2647     y = -10; height = 5;
2648     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2649     expect(Ok, status);
2650     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2651
2652     status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2653     expect(Ok, status);
2654
2655     /* entirely within the visible region */
2656     x = 12; width = 10;
2657     y = 22; height = 10;
2658     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2659     expect(Ok, status);
2660     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2661
2662     /* partially outside */
2663     x = 35; width = 10;
2664     y = 55; height = 10;
2665     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2666     expect(Ok, status);
2667     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2668
2669     /* entirely outside */
2670     x = 45; width = 5;
2671     y = 65; height = 5;
2672     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2673     expect(Ok, status);
2674     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2675
2676     /* translate into center of clipping rect */
2677     GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2678
2679     x = 0; width = 10;
2680     y = 0; height = 10;
2681     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2682     expect(Ok, status);
2683     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2684
2685     x = 25; width = 5;
2686     y = 40; height = 5;
2687     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2688     expect(Ok, status);
2689     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2690
2691     GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2692
2693     /* corners entirely outside, but some intersections */
2694     x = 0; width = 70;
2695     y = 0; height = 90;
2696     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2697     expect(Ok, status);
2698     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2699
2700     x = 0; width = 70;
2701     y = 0; height = 30;
2702     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2703     expect(Ok, status);
2704     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2705
2706     x = 0; width = 30;
2707     y = 0; height = 90;
2708     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2709     expect(Ok, status);
2710     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2711
2712     /* edge cases */
2713     x = 0; width = 10;
2714     y = 20; height = 40;
2715     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2716     expect(Ok, status);
2717     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2718
2719     x = 10; width = 30;
2720     y = 0; height = 20;
2721     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2722     expect(Ok, status);
2723     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2724
2725     x = 40; width = 10;
2726     y = 20; height = 40;
2727     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2728     expect(Ok, status);
2729     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2730
2731     x = 10; width = 30;
2732     y = 60; height = 10;
2733     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2734     expect(Ok, status);
2735     ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2736
2737     /* rounding tests */
2738     x = 0.4; width = 10.4;
2739     y = 20; height = 40;
2740     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2741     expect(Ok, status);
2742     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2743
2744     x = 10; width = 30;
2745     y = 0.4; height = 20.4;
2746     status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2747     expect(Ok, status);
2748     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2749
2750     /* integer version */
2751     x = 0; width = 30;
2752     y = 0; height = 90;
2753     status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2754     expect(Ok, status);
2755     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2756
2757     x = 12; width = 10;
2758     y = 22; height = 10;
2759     status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2760     expect(Ok, status);
2761     ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2762
2763     GdipDeleteGraphics(graphics);
2764     ReleaseDC(hwnd, hdc);
2765 }
2766
2767 static void test_GdipGetNearestColor(void)
2768 {
2769     GpStatus status;
2770     GpGraphics *graphics;
2771     GpBitmap *bitmap;
2772     ARGB color = 0xdeadbeef;
2773     HDC hdc = GetDC( hwnd );
2774
2775     /* create a graphics object */
2776     ok(hdc != NULL, "Expected HDC to be initialized\n");
2777
2778     status = GdipCreateFromHDC(hdc, &graphics);
2779     expect(Ok, status);
2780     ok(graphics != NULL, "Expected graphics to be initialized\n");
2781
2782     status = GdipGetNearestColor(graphics, NULL);
2783     expect(InvalidParameter, status);
2784
2785     status = GdipGetNearestColor(NULL, &color);
2786     expect(InvalidParameter, status);
2787     GdipDeleteGraphics(graphics);
2788
2789     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, &bitmap);
2790     expect(Ok, status);
2791     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2792     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2793     if (status == Ok)
2794     {
2795         status = GdipGetNearestColor(graphics, &color);
2796         expect(Ok, status);
2797         expect(0xdeadbeef, color);
2798         GdipDeleteGraphics(graphics);
2799     }
2800     GdipDisposeImage((GpImage*)bitmap);
2801
2802     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, &bitmap);
2803     expect(Ok, status);
2804     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2805     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2806     if (status == Ok)
2807     {
2808         status = GdipGetNearestColor(graphics, &color);
2809         expect(Ok, status);
2810         expect(0xdeadbeef, color);
2811         GdipDeleteGraphics(graphics);
2812     }
2813     GdipDisposeImage((GpImage*)bitmap);
2814
2815     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, &bitmap);
2816     expect(Ok, status);
2817     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2818     ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2819     if (status == Ok)
2820     {
2821         status = GdipGetNearestColor(graphics, &color);
2822         expect(Ok, status);
2823         expect(0xdeadbeef, color);
2824         GdipDeleteGraphics(graphics);
2825     }
2826     GdipDisposeImage((GpImage*)bitmap);
2827
2828     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, &bitmap);
2829     expect(Ok, status);
2830     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2831     todo_wine expect(OutOfMemory, status);
2832     if (status == Ok)
2833         GdipDeleteGraphics(graphics);
2834     GdipDisposeImage((GpImage*)bitmap);
2835
2836     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bitmap);
2837     expect(Ok, status);
2838     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2839     expect(Ok, status);
2840     status = GdipGetNearestColor(graphics, &color);
2841     expect(Ok, status);
2842     expect(0xdeadbeef, color);
2843     GdipDeleteGraphics(graphics);
2844     GdipDisposeImage((GpImage*)bitmap);
2845
2846     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, &bitmap);
2847     expect(Ok, status);
2848     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2849     expect(Ok, status);
2850     status = GdipGetNearestColor(graphics, &color);
2851     expect(Ok, status);
2852     expect(0xdeadbeef, color);
2853     GdipDeleteGraphics(graphics);
2854     GdipDisposeImage((GpImage*)bitmap);
2855
2856     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, &bitmap);
2857     expect(Ok, status);
2858     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2859     expect(Ok, status);
2860     status = GdipGetNearestColor(graphics, &color);
2861     expect(Ok, status);
2862     expect(0xdeadbeef, color);
2863     GdipDeleteGraphics(graphics);
2864     GdipDisposeImage((GpImage*)bitmap);
2865
2866     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, &bitmap);
2867     expect(Ok, status);
2868     if (status == Ok)
2869     {
2870         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2871         expect(Ok, status);
2872         status = GdipGetNearestColor(graphics, &color);
2873         expect(Ok, status);
2874         expect(0xdeadbeef, color);
2875         GdipDeleteGraphics(graphics);
2876         GdipDisposeImage((GpImage*)bitmap);
2877     }
2878
2879     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, &bitmap);
2880     expect(Ok, status);
2881     if (status == Ok)
2882     {
2883         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2884         expect(Ok, status);
2885         status = GdipGetNearestColor(graphics, &color);
2886         expect(Ok, status);
2887         expect(0xdeadbeef, color);
2888         GdipDeleteGraphics(graphics);
2889         GdipDisposeImage((GpImage*)bitmap);
2890     }
2891
2892     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, &bitmap);
2893     expect(Ok, status);
2894     if (status == Ok)
2895     {
2896         status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2897         expect(Ok, status);
2898         status = GdipGetNearestColor(graphics, &color);
2899         expect(Ok, status);
2900         expect(0xdeadbeef, color);
2901         GdipDeleteGraphics(graphics);
2902         GdipDisposeImage((GpImage*)bitmap);
2903     }
2904
2905     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, &bitmap);
2906     expect(Ok, status);
2907     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2908     expect(Ok, status);
2909     status = GdipGetNearestColor(graphics, &color);
2910     expect(Ok, status);
2911     todo_wine expect(0xffa8bce8, color);
2912     GdipDeleteGraphics(graphics);
2913     GdipDisposeImage((GpImage*)bitmap);
2914
2915     status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, &bitmap);
2916     expect(Ok, status);
2917     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2918     expect(Ok, status);
2919     status = GdipGetNearestColor(graphics, &color);
2920     expect(Ok, status);
2921     todo_wine
2922     ok(color == 0xffa8b8e8 ||
2923        broken(color == 0xffa0b8e0), /* Win98/WinMe */
2924        "Expected ffa8b8e8, got %.8x\n", color);
2925     GdipDeleteGraphics(graphics);
2926     GdipDisposeImage((GpImage*)bitmap);
2927
2928     ReleaseDC(hwnd, hdc);
2929 }
2930
2931 static void test_string_functions(void)
2932 {
2933     GpStatus status;
2934     GpGraphics *graphics;
2935     GpFontFamily *family;
2936     GpFont *font;
2937     RectF rc, char_bounds, bounds;
2938     GpBrush *brush;
2939     ARGB color = 0xff000000;
2940     HDC hdc = GetDC( hwnd );
2941     const WCHAR fontname[] = {'T','a','h','o','m','a',0};
2942     const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
2943     const WCHAR teststring2[] = {'j',0};
2944     REAL char_width, char_height;
2945     INT codepointsfitted, linesfilled;
2946     GpStringFormat *format;
2947     CharacterRange ranges[3] = {{0, 1}, {1, 3}, {5, 1}};
2948     GpRegion *regions[4];
2949     BOOL region_isempty[4];
2950     int i;
2951     PointF positions[8];
2952     GpMatrix *identity;
2953
2954     ok(hdc != NULL, "Expected HDC to be initialized\n");
2955     status = GdipCreateFromHDC(hdc, &graphics);
2956     expect(Ok, status);
2957     ok(graphics != NULL, "Expected graphics to be initialized\n");
2958
2959     status = GdipCreateFontFamilyFromName(fontname, NULL, &family);
2960     expect(Ok, status);
2961
2962     status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font);
2963     expect(Ok, status);
2964
2965     status = GdipCreateSolidFill(color, (GpSolidFill**)&brush);
2966     expect(Ok, status);
2967
2968     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
2969     expect(Ok, status);
2970
2971     rc.X = 0;
2972     rc.Y = 0;
2973     rc.Width = 100.0;
2974     rc.Height = 100.0;
2975
2976     status = GdipDrawString(NULL, teststring, 6, font, &rc, NULL, brush);
2977     expect(InvalidParameter, status);
2978
2979     status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush);
2980     expect(InvalidParameter, status);
2981
2982     status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush);
2983     expect(InvalidParameter, status);
2984
2985     status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush);
2986     expect(InvalidParameter, status);
2987
2988     status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL);
2989     expect(InvalidParameter, status);
2990
2991     status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, brush);
2992     expect(Ok, status);
2993
2994     status = GdipMeasureString(NULL, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2995     expect(InvalidParameter, status);
2996
2997     status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2998     expect(InvalidParameter, status);
2999
3000     status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3001     expect(InvalidParameter, status);
3002
3003     status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled);
3004     expect(InvalidParameter, status);
3005
3006     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled);
3007     expect(InvalidParameter, status);
3008
3009     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, NULL, &linesfilled);
3010     expect(Ok, status);
3011
3012     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, NULL);
3013     expect(Ok, status);
3014
3015     status = GdipMeasureString(graphics, teststring, 1, font, &rc, NULL, &char_bounds, &codepointsfitted, &linesfilled);
3016     expect(Ok, status);
3017     expectf(0.0, char_bounds.X);
3018     expectf(0.0, char_bounds.Y);
3019     ok(char_bounds.Width > 0, "got %0.2f\n", bounds.Width);
3020     ok(char_bounds.Height > 0, "got %0.2f\n", bounds.Height);
3021     expect(1, codepointsfitted);
3022     expect(1, linesfilled);
3023
3024     status = GdipMeasureString(graphics, teststring, 2, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3025     expect(Ok, status);
3026     expectf(0.0, bounds.X);
3027     expectf(0.0, bounds.Y);
3028     ok(bounds.Width > char_bounds.Width, "got %0.2f, expected at least %0.2f\n", bounds.Width, char_bounds.Width);
3029     expectf(char_bounds.Height, bounds.Height);
3030     expect(2, codepointsfitted);
3031     expect(1, linesfilled);
3032     char_width = bounds.Width - char_bounds.Width;
3033
3034     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3035     expect(Ok, status);
3036     expectf(0.0, bounds.X);
3037     expectf(0.0, bounds.Y);
3038     ok(bounds.Width > char_bounds.Width + char_width * 2, "got %0.2f, expected at least %0.2f\n",
3039        bounds.Width, char_bounds.Width + char_width * 2);
3040     ok(bounds.Height > char_bounds.Height, "got %0.2f, expected at least %0.2f\n", bounds.Height, char_bounds.Height);
3041     expect(6, codepointsfitted);
3042     expect(2, linesfilled);
3043     char_height = bounds.Height - char_bounds.Height;
3044
3045     /* Cut off everything after the first space. */
3046     rc.Width = char_bounds.Width + char_width * 2.1;
3047
3048     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3049     expect(Ok, status);
3050     expectf(0.0, bounds.X);
3051     expectf(0.0, bounds.Y);
3052     expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
3053     expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
3054     expect(6, codepointsfitted);
3055     expect(3, linesfilled);
3056
3057     /* Cut off everything including the first space. */
3058     rc.Width = char_bounds.Width + char_width * 1.7;
3059
3060     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3061     expect(Ok, status);
3062     expectf(0.0, bounds.X);
3063     expectf(0.0, bounds.Y);
3064     expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
3065     expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
3066     expect(6, codepointsfitted);
3067     expect(3, linesfilled);
3068
3069     /* Cut off everything after the first character. */
3070     rc.Width = char_bounds.Width + char_width * 0.8;
3071
3072     status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3073     expect(Ok, status);
3074     expectf(0.0, bounds.X);
3075     expectf(0.0, bounds.Y);
3076     expectf_(char_bounds.Width, bounds.Width, 0.01);
3077     todo_wine expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
3078     expect(6, codepointsfitted);
3079     todo_wine expect(4, linesfilled);
3080
3081     for (i = 0; i < 4; i++)
3082         regions[i] = (GpRegion *)0xdeadbeef;
3083
3084     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 0, regions);
3085     expect(Ok, status);
3086
3087     for (i = 0; i < 4; i++)
3088         ok(regions[i] == (GpRegion *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", regions[i]);
3089
3090     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3091     expect(Ok, status);
3092
3093     for (i = 0; i < 4; i++)
3094         ok(regions[i] == (GpRegion *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", regions[i]);
3095
3096     status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
3097     expect(Ok, status);
3098
3099     set_rect_empty(&rc);
3100
3101     for (i=0; i<4; i++)
3102     {
3103         status = GdipCreateRegion(&regions[i]);
3104         expect(Ok, status);
3105         status = GdipSetEmpty(regions[i]);
3106         expect(Ok, status);
3107     }
3108
3109     status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions);
3110     expect(InvalidParameter, status);
3111
3112     status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
3113     expect(InvalidParameter, status);
3114
3115     status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
3116     expect(InvalidParameter, status);
3117
3118     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
3119     expect(InvalidParameter, status);
3120
3121     if (0)
3122     {
3123         /* Crashes on Windows XP */
3124         status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
3125         expect(InvalidParameter, status);
3126     }
3127
3128     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL);
3129     expect(InvalidParameter, status);
3130
3131     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions);
3132     expect(InvalidParameter, status);
3133
3134     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3135     expect(Ok, status);
3136
3137     for (i = 0; i < 4; i++)
3138     {
3139         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3140         expect(Ok, status);
3141     }
3142
3143     ok(region_isempty[0], "region should be empty\n");
3144     ok(region_isempty[1], "region should be empty\n");
3145     ok(region_isempty[2], "region should be empty\n");
3146     ok(region_isempty[3], "region should be empty\n");
3147
3148     rc.Width = 100.0;
3149     rc.Height = 100.0;
3150
3151     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions);
3152     expect(Ok, status);
3153
3154     for (i=0; i<4; i++)
3155     {
3156         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3157         expect(Ok, status);
3158     }
3159
3160     ok(!region_isempty[0], "region shouldn't be empty\n");
3161     ok(!region_isempty[1], "region shouldn't be empty\n");
3162     ok(!region_isempty[2], "region shouldn't be empty\n");
3163     ok(region_isempty[3], "region should be empty\n");
3164
3165     /* Cut off everything after the first space, and the second line. */
3166     rc.Width = char_bounds.Width + char_width * 2.1;
3167     rc.Height = char_bounds.Height + char_height * 0.5;
3168
3169     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3170     expect(Ok, status);
3171
3172     for (i=0; i<4; i++)
3173     {
3174         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3175         expect(Ok, status);
3176     }
3177
3178     ok(!region_isempty[0], "region shouldn't be empty\n");
3179     ok(!region_isempty[1], "region shouldn't be empty\n");
3180     ok(region_isempty[2], "region should be empty\n");
3181     ok(region_isempty[3], "region should be empty\n");
3182
3183     for (i=0; i<4; i++)
3184         GdipDeleteRegion(regions[i]);
3185
3186     status = GdipCreateMatrix(&identity);
3187     expect(Ok, status);
3188
3189     rc.X = 0;
3190     rc.Y = 0;
3191     rc.Width = 0;
3192     rc.Height = 0;
3193     memset(positions, 0, sizeof(positions));
3194     status = GdipMeasureDriverString(NULL, teststring, 6, font, positions,
3195         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3196         identity, &rc);
3197     expect(InvalidParameter, status);
3198
3199     status = GdipMeasureDriverString(graphics, NULL, 6, font, positions,
3200         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3201         identity, &rc);
3202     expect(InvalidParameter, status);
3203
3204     status = GdipMeasureDriverString(graphics, teststring, 6, NULL, positions,
3205         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3206         identity, &rc);
3207     expect(InvalidParameter, status);
3208
3209     status = GdipMeasureDriverString(graphics, teststring, 6, font, NULL,
3210         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3211         identity, &rc);
3212     expect(InvalidParameter, status);
3213
3214     status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3215         0x100, identity, &rc);
3216     expect(Ok, status);
3217
3218     status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3219         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3220         NULL, &rc);
3221     expect(Ok, status);
3222
3223     status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3224         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3225         identity, NULL);
3226     expect(InvalidParameter, status);
3227
3228     rc.X = 0;
3229     rc.Y = 0;
3230     rc.Width = 0;
3231     rc.Height = 0;
3232     status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3233         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3234         identity, &rc);
3235     expect(Ok, status);
3236
3237     expectf(0.0, rc.X);
3238     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3239     ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width);
3240     ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y);
3241
3242     char_width = rc.Width;
3243     char_height = rc.Height;
3244
3245     rc.X = 0;
3246     rc.Y = 0;
3247     rc.Width = 0;
3248     rc.Height = 0;
3249     status = GdipMeasureDriverString(graphics, teststring, 4, font, positions,
3250         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3251         identity, &rc);
3252     expect(Ok, status);
3253
3254     expectf(0.0, rc.X);
3255     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3256     ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width);
3257     expectf(char_height, rc.Height);
3258
3259     rc.X = 0;
3260     rc.Y = 0;
3261     rc.Width = 0;
3262     rc.Height = 0;
3263     status = GdipMeasureDriverString(graphics, teststring2, 1, font, positions,
3264         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3265         identity, &rc);
3266     expect(Ok, status);
3267
3268     expectf(rc.X, 0.0);
3269     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3270     ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width);
3271     expectf(rc.Height, char_height);
3272
3273     GdipDeleteMatrix(identity);
3274     GdipDeleteStringFormat(format);
3275     GdipDeleteBrush(brush);
3276     GdipDeleteFont(font);
3277     GdipDeleteFontFamily(family);
3278     GdipDeleteGraphics(graphics);
3279
3280     ReleaseDC(hwnd, hdc);
3281 }
3282
3283 static void test_get_set_interpolation(void)
3284 {
3285     GpGraphics *graphics;
3286     HDC hdc = GetDC( hwnd );
3287     GpStatus status;
3288     InterpolationMode mode;
3289
3290     ok(hdc != NULL, "Expected HDC to be initialized\n");
3291     status = GdipCreateFromHDC(hdc, &graphics);
3292     expect(Ok, status);
3293     ok(graphics != NULL, "Expected graphics to be initialized\n");
3294
3295     status = GdipGetInterpolationMode(NULL, &mode);
3296     expect(InvalidParameter, status);
3297
3298     if (0)
3299     {
3300         /* Crashes on Windows XP */
3301         status = GdipGetInterpolationMode(graphics, NULL);
3302         expect(InvalidParameter, status);
3303     }
3304
3305     status = GdipSetInterpolationMode(NULL, InterpolationModeNearestNeighbor);
3306     expect(InvalidParameter, status);
3307
3308     /* out of range */
3309     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBicubic+1);
3310     expect(InvalidParameter, status);
3311
3312     status = GdipSetInterpolationMode(graphics, InterpolationModeInvalid);
3313     expect(InvalidParameter, status);
3314
3315     status = GdipGetInterpolationMode(graphics, &mode);
3316     expect(Ok, status);
3317     expect(InterpolationModeBilinear, mode);
3318
3319     status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3320     expect(Ok, status);
3321
3322     status = GdipGetInterpolationMode(graphics, &mode);
3323     expect(Ok, status);
3324     expect(InterpolationModeNearestNeighbor, mode);
3325
3326     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
3327     expect(Ok, status);
3328
3329     status = GdipGetInterpolationMode(graphics, &mode);
3330     expect(Ok, status);
3331     expect(InterpolationModeBilinear, mode);
3332
3333     status = GdipSetInterpolationMode(graphics, InterpolationModeLowQuality);
3334     expect(Ok, status);
3335
3336     status = GdipGetInterpolationMode(graphics, &mode);
3337     expect(Ok, status);
3338     expect(InterpolationModeBilinear, mode);
3339
3340     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality);
3341     expect(Ok, status);
3342
3343     status = GdipGetInterpolationMode(graphics, &mode);
3344     expect(Ok, status);
3345     expect(InterpolationModeHighQualityBicubic, mode);
3346
3347     GdipDeleteGraphics(graphics);
3348
3349     ReleaseDC(hwnd, hdc);
3350 }
3351
3352 static void test_get_set_textrenderinghint(void)
3353 {
3354     GpGraphics *graphics;
3355     HDC hdc = GetDC( hwnd );
3356     GpStatus status;
3357     TextRenderingHint hint;
3358
3359     ok(hdc != NULL, "Expected HDC to be initialized\n");
3360     status = GdipCreateFromHDC(hdc, &graphics);
3361     expect(Ok, status);
3362     ok(graphics != NULL, "Expected graphics to be initialized\n");
3363
3364     status = GdipGetTextRenderingHint(NULL, &hint);
3365     expect(InvalidParameter, status);
3366
3367     status = GdipGetTextRenderingHint(graphics, NULL);
3368     expect(InvalidParameter, status);
3369
3370     status = GdipSetTextRenderingHint(NULL, TextRenderingHintAntiAlias);
3371     expect(InvalidParameter, status);
3372
3373     /* out of range */
3374     status = GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit+1);
3375     expect(InvalidParameter, status);
3376
3377     status = GdipGetTextRenderingHint(graphics, &hint);
3378     expect(Ok, status);
3379     expect(TextRenderingHintSystemDefault, hint);
3380
3381     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
3382     expect(Ok, status);
3383
3384     status = GdipGetTextRenderingHint(graphics, &hint);
3385     expect(Ok, status);
3386     expect(TextRenderingHintSystemDefault, hint);
3387
3388     status = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAliasGridFit);
3389     expect(Ok, status);
3390
3391     status = GdipGetTextRenderingHint(graphics, &hint);
3392     expect(Ok, status);
3393     expect(TextRenderingHintAntiAliasGridFit, hint);
3394
3395     GdipDeleteGraphics(graphics);
3396
3397     ReleaseDC(hwnd, hdc);
3398 }
3399
3400 static void test_getdc_scaled(void)
3401 {
3402     GpStatus status;
3403     GpGraphics *graphics = NULL;
3404     GpBitmap *bitmap = NULL;
3405     HDC hdc=NULL;
3406     HBRUSH hbrush, holdbrush;
3407     ARGB color;
3408
3409     status = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, NULL, &bitmap);
3410     expect(Ok, status);
3411
3412     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
3413     expect(Ok, status);
3414
3415     status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
3416     expect(Ok, status);
3417
3418     status = GdipGetDC(graphics, &hdc);
3419     expect(Ok, status);
3420     ok(hdc != NULL, "got NULL hdc\n");
3421
3422     hbrush = CreateSolidBrush(RGB(255, 0, 0));
3423
3424     holdbrush = SelectObject(hdc, hbrush);
3425
3426     Rectangle(hdc, 2, 2, 6, 6);
3427
3428     SelectObject(hdc, holdbrush);
3429
3430     DeleteObject(hbrush);
3431
3432     status = GdipReleaseDC(graphics, hdc);
3433     expect(Ok, status);
3434
3435     GdipDeleteGraphics(graphics);
3436
3437     status = GdipBitmapGetPixel(bitmap, 3, 3, &color);
3438     expect(Ok, status);
3439     expect(0xffff0000, color);
3440
3441     status = GdipBitmapGetPixel(bitmap, 8, 8, &color);
3442     expect(Ok, status);
3443     expect(0xff000000, color);
3444
3445     GdipDisposeImage((GpImage*)bitmap);
3446 }
3447
3448 static void test_GdipMeasureString(void)
3449 {
3450     static const struct test_data
3451     {
3452         REAL res_x, res_y, page_scale;
3453         GpUnit unit;
3454     } td[] =
3455     {
3456         { 200.0, 200.0, 1.0, UnitPixel }, /* base */
3457         { 200.0, 200.0, 2.0, UnitPixel },
3458         { 200.0, 200.0, 1.0, UnitDisplay },
3459         { 200.0, 200.0, 2.0, UnitDisplay },
3460         { 200.0, 200.0, 1.0, UnitInch },
3461         { 200.0, 200.0, 2.0, UnitInch },
3462         { 200.0, 600.0, 1.0, UnitPoint },
3463         { 200.0, 600.0, 2.0, UnitPoint },
3464         { 200.0, 600.0, 1.0, UnitDocument },
3465         { 200.0, 600.0, 2.0, UnitDocument },
3466         { 200.0, 600.0, 1.0, UnitMillimeter },
3467         { 200.0, 600.0, 2.0, UnitMillimeter },
3468         { 200.0, 600.0, 1.0, UnitDisplay },
3469         { 200.0, 600.0, 2.0, UnitDisplay },
3470         { 200.0, 600.0, 1.0, UnitPixel },
3471         { 200.0, 600.0, 2.0, UnitPixel },
3472     };
3473     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3474     static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3475     GpStatus status;
3476     GpGraphics *graphics;
3477     GpFontFamily *family;
3478     GpFont *font;
3479     GpStringFormat *format;
3480     RectF bounds, rc;
3481     REAL base_cx = 0, base_cy = 0, height;
3482     INT chars, lines;
3483     LOGFONTW lf;
3484     UINT i;
3485     REAL font_size;
3486     GpUnit font_unit, unit;
3487
3488     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
3489     expect(Ok, status);
3490     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3491     expect(Ok, status);
3492
3493     /* font size in pixels */
3494     status = GdipCreateFont(family, 100.0, FontStyleRegular, UnitPixel, &font);
3495     expect(Ok, status);
3496     status = GdipGetFontSize(font, &font_size);
3497     expect(Ok, status);
3498     expectf(100.0, font_size);
3499     status = GdipGetFontUnit(font, &font_unit);
3500     expect(Ok, status);
3501     expect(UnitPixel, font_unit);
3502
3503     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3504     {
3505         graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale);
3506
3507         lf.lfHeight = 0xdeadbeef;
3508         status = GdipGetLogFontW(font, graphics, &lf);
3509         expect(Ok, status);
3510         height = units_to_pixels(font_size, td[i].unit, td[i].res_y);
3511         if (td[i].unit != UnitDisplay)
3512             height *= td[i].page_scale;
3513         ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3514            i, (LONG)(height + 0.5), height, lf.lfHeight);
3515
3516         height = font_size + 2.0 * font_size / 6.0;
3517
3518         set_rect_empty(&rc);
3519         set_rect_empty(&bounds);
3520         status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3521         expect(Ok, status);
3522
3523         if (i == 0)
3524         {
3525             base_cx = bounds.Width;
3526             base_cy = bounds.Height;
3527         }
3528
3529         expectf(0.0, bounds.X);
3530         expectf(0.0, bounds.Y);
3531 todo_wine
3532         expectf_(height, bounds.Height, height / 100.0);
3533         expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3534         expect(7, chars);
3535         expect(1, lines);
3536
3537         /* make sure it really fits */
3538         bounds.Width += 1.0;
3539         bounds.Height += 1.0;
3540         rc = bounds;
3541         rc.X = 50.0;
3542         rc.Y = 50.0;
3543         set_rect_empty(&bounds);
3544         status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3545         expect(Ok, status);
3546         expectf(50.0, bounds.X);
3547         expectf(50.0, bounds.Y);
3548 todo_wine
3549         expectf_(height, bounds.Height, height / 100.0);
3550         expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3551         expect(7, chars);
3552         expect(1, lines);
3553
3554         status = GdipDeleteGraphics(graphics);
3555         expect(Ok, status);
3556     }
3557
3558     GdipDeleteFont(font);
3559
3560     /* font size in logical units */
3561     /* UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3562     for (unit = 3; unit <= 6; unit++)
3563     {
3564         /* create a font which final height is 100.0 pixels with 200 dpi device */
3565         /* height + 2 * (height/6) = 100 => height = 100 * 3 / 4 => 75 */
3566         height = pixels_to_units(75.0, unit, 200.0);
3567         status = GdipCreateFont(family, height, FontStyleRegular, unit, &font);
3568         expect(Ok, status);
3569         status = GdipGetFontSize(font, &font_size);
3570         expect(Ok, status);
3571         expectf(height, font_size);
3572         status = GdipGetFontUnit(font, &font_unit);
3573         expect(Ok, status);
3574         expect(unit, font_unit);
3575
3576         for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3577         {
3578             REAL unit_scale;
3579
3580             graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale);
3581
3582             lf.lfHeight = 0xdeadbeef;
3583             status = GdipGetLogFontW(font, graphics, &lf);
3584             expect(Ok, status);
3585             if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3586                 height = units_to_pixels(font_size, font_unit, td[i].res_x);
3587             else
3588                 height = units_to_pixels(font_size, font_unit, td[i].res_y);
3589             /*trace("%.1f font units = %f pixels with %.1f dpi, page_scale %.1f\n", font_size, height, td[i].res_y, td[i].page_scale);*/
3590             ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3591                i, (LONG)(height + 0.5), height, lf.lfHeight);
3592
3593             if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3594                 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_x);
3595             else
3596                 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_y);
3597             /*trace("%u: %d to %d, %.1f dpi => unit_scale %f\n", i, font_unit, td[i].unit, td[i].res_y, unit_scale);*/
3598             height = (font_size + 2.0 * font_size / 6.0) * unit_scale;
3599             if (td[i].unit != UnitDisplay)
3600                 height /= td[i].page_scale;
3601             /*trace("%u: %.1f font units = %f units with %.1f dpi, page_scale %.1f\n", i, font_size, height, td[i].res_y, td[i].page_scale);*/
3602
3603             set_rect_empty(&rc);
3604             set_rect_empty(&bounds);
3605             status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3606             expect(Ok, status);
3607
3608             if (i == 0)
3609             {
3610                 base_cx = bounds.Width;
3611                 base_cy = bounds.Height;
3612             }
3613
3614             expectf(0.0, bounds.X);
3615             expectf(0.0, bounds.Y);
3616 todo_wine
3617             expectf_(height, bounds.Height, height / 85.0);
3618             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3619             expect(7, chars);
3620             expect(1, lines);
3621
3622             /* make sure it really fits */
3623             bounds.Width += 1.0;
3624             bounds.Height += 1.0;
3625             rc = bounds;
3626             rc.X = 50.0;
3627             rc.Y = 50.0;
3628             set_rect_empty(&bounds);
3629             status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3630             expect(Ok, status);
3631             expectf(50.0, bounds.X);
3632             expectf(50.0, bounds.Y);
3633 todo_wine
3634             expectf_(height, bounds.Height, height / 85.0);
3635             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3636             expect(7, chars);
3637             expect(1, lines);
3638
3639             /* verify the result */
3640             height = units_to_pixels(bounds.Height, td[i].unit, td[i].res_x);
3641             if (td[i].unit != UnitDisplay)
3642                 height *= td[i].page_scale;
3643             /*trace("%u: unit %u, %.1fx%.1f dpi, scale %.1f, height %f, pixels %f\n",
3644                   i, td[i].unit, td[i].res_x, td[i].res_y, td[i].page_scale, bounds.Height, height);*/
3645 todo_wine
3646             expectf_(100.0, height, 1.1);
3647
3648             status = GdipDeleteGraphics(graphics);
3649             expect(Ok, status);
3650         }
3651
3652         GdipDeleteFont(font);
3653     }
3654
3655     GdipDeleteFontFamily(family);
3656     GdipDeleteStringFormat(format);
3657 }
3658
3659 static void test_transform(void)
3660 {
3661     static const struct test_data
3662     {
3663         REAL res_x, res_y, scale;
3664         GpUnit unit;
3665         GpPointF in[2], out[2];
3666     } td[] =
3667     {
3668         { 96.0, 96.0, 1.0, UnitPixel,
3669           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3670         { 96.0, 96.0, 1.0, UnitDisplay,
3671           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3672         { 96.0, 96.0, 1.0, UnitInch,
3673           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 9600.0, 0.0 }, { 0.0, 9600.0 } } },
3674         { 123.0, 456.0, 1.0, UnitPoint,
3675           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 170.833313, 0.0 }, { 0.0, 633.333252 } } },
3676         { 123.0, 456.0, 1.0, UnitDocument,
3677           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 40.999996, 0.0 }, { 0.0, 151.999985 } } },
3678         { 123.0, 456.0, 2.0, UnitMillimeter,
3679           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 968.503845, 0.0 }, { 0.0, 3590.550781 } } },
3680         { 196.0, 296.0, 1.0, UnitDisplay,
3681           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3682         { 196.0, 296.0, 1.0, UnitPixel,
3683           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3684     };
3685     GpStatus status;
3686     GpGraphics *graphics;
3687     GpPointF ptf[2];
3688     UINT i;
3689
3690     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3691     {
3692         graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].scale);
3693         ptf[0].X = td[i].in[0].X;
3694         ptf[0].Y = td[i].in[0].Y;
3695         ptf[1].X = td[i].in[1].X;
3696         ptf[1].Y = td[i].in[1].Y;
3697         status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
3698         expect(Ok, status);
3699         expectf(td[i].out[0].X, ptf[0].X);
3700         expectf(td[i].out[0].Y, ptf[0].Y);
3701         expectf(td[i].out[1].X, ptf[1].X);
3702         expectf(td[i].out[1].Y, ptf[1].Y);
3703         status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
3704         expect(Ok, status);
3705         expectf(td[i].in[0].X, ptf[0].X);
3706         expectf(td[i].in[0].Y, ptf[0].Y);
3707         expectf(td[i].in[1].X, ptf[1].X);
3708         expectf(td[i].in[1].Y, ptf[1].Y);
3709         status = GdipDeleteGraphics(graphics);
3710         expect(Ok, status);
3711     }
3712 }
3713
3714 /* Many people on the net ask why there is so much difference in rendered
3715  * text height between gdiplus and gdi32, this test suggests an answer to
3716  * that question. Important: this test assumes that font dpi == device dpi.
3717  */
3718 static void test_font_height_scaling(void)
3719 {
3720     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3721     static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3722     HDC hdc;
3723     GpStringFormat *format;
3724     CharacterRange range = { 0, 7 };
3725     GpRegion *region;
3726     GpGraphics *graphics;
3727     GpFontFamily *family;
3728     GpFont *font;
3729     GpStatus status;
3730     RectF bounds, rect;
3731     REAL height, dpi, scale;
3732     PointF ptf;
3733     GpUnit gfx_unit, font_unit;
3734
3735     status = GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &format);
3736     expect(Ok, status);
3737     status = GdipSetStringFormatMeasurableCharacterRanges(format, 1, &range);
3738     expect(Ok, status);
3739     status = GdipCreateRegion(&region);
3740     expect(Ok, status);
3741
3742     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3743     expect(Ok, status);
3744
3745     hdc = CreateCompatibleDC(0);
3746     status = GdipCreateFromHDC(hdc, &graphics);
3747
3748     status = GdipGetDpiY(graphics, &dpi);
3749     expect(Ok, status);
3750
3751     /* First check if tested functionality works:
3752      * under XP if font and graphics units differ then GdipTransformPoints
3753      * followed by GdipSetPageUnit to change the graphics units breaks region
3754      * scaling in GdipMeasureCharacterRanges called later.
3755      */
3756     status = GdipSetPageUnit(graphics, UnitDocument);
3757     expect(Ok, status);
3758
3759     ptf.X = 0.0;
3760     ptf.Y = 0.0;
3761     status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3762     expect(Ok, status);
3763
3764     status = GdipSetPageUnit(graphics, UnitInch);
3765     expect(Ok, status);
3766
3767     status = GdipCreateFont(family, 720.0, FontStyleRegular, UnitPoint, &font);
3768     expect(Ok, status);
3769
3770     set_rect_empty(&rect);
3771     set_rect_empty(&bounds);
3772     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
3773     expect(Ok, status);
3774     trace("test bounds: %f,%f,%f,%f\n", bounds.X, bounds.Y, bounds.Width, bounds.Height);
3775
3776     set_rect_empty(&rect);
3777     rect.Width = 32000.0;
3778     rect.Height = 32000.0;
3779     status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
3780     expect(Ok, status);
3781
3782     set_rect_empty(&rect);
3783     status = GdipGetRegionBounds(region, graphics, &rect);
3784     expect(Ok, status);
3785     trace("test region: %f,%f,%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);
3786
3787     GdipDeleteFont(font);
3788
3789     scale = rect.Height / bounds.Height;
3790     if (fabs(scale - 1.0) > 0.1)
3791     {
3792         win_skip("GdipGetRegionBounds is broken, scale %f (should be near 1.0)\n", scale);
3793         goto cleanup;
3794     }
3795
3796     status = GdipScaleWorldTransform(graphics, 0.01, 0.01, MatrixOrderAppend);
3797     expect(Ok, status);
3798
3799     /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3800     /* UnitPixel as a font base unit is not tested because it drastically
3801        differs in behaviour */
3802     for (font_unit = 3; font_unit <= 6; font_unit++)
3803     {
3804         /* create a font for the final text height of 100 pixels */
3805         /* height + 2 * (height/6) = 100 => height = 100 * 3 / 4 => 75 */
3806         status = GdipSetPageUnit(graphics, font_unit);
3807         expect(Ok, status);
3808         ptf.X = 0;
3809         ptf.Y = 75.0;
3810         status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3811         expect(Ok, status);
3812         height = ptf.Y;
3813         /*trace("height %f units\n", height);*/
3814         status = GdipCreateFont(family, height, FontStyleRegular, font_unit, &font);
3815         expect(Ok, status);
3816
3817         /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3818         for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
3819         {
3820             static const WCHAR doubleW[2] = { 'W','W' };
3821             RectF bounds_1, bounds_2;
3822             REAL margin, margin_y, font_height;
3823             int match;
3824
3825             status = GdipSetPageUnit(graphics, gfx_unit);
3826             expect(Ok, status);
3827
3828             margin_y = units_to_pixels(height / 8.0, font_unit, dpi);
3829             margin_y = pixels_to_units(margin_y, gfx_unit, dpi);
3830
3831             status = GdipGetFontHeight(font, graphics, &font_height);
3832             expect(Ok, status);
3833
3834             set_rect_empty(&rect);
3835             set_rect_empty(&bounds);
3836             status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
3837             expect(Ok, status);
3838             /*trace("bounds: %f,%f,%f,%f\n", bounds.X, bounds.Y, bounds.Width, bounds.Height);*/
3839 todo_wine
3840             expectf_(font_height + margin_y, bounds.Height, 0.005);
3841
3842             ptf.X = 0;
3843             ptf.Y = bounds.Height;
3844             status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &ptf, 1);
3845             expect(Ok, status);
3846             match = fabs(100.0 - ptf.Y) <= 1.0;
3847 todo_wine
3848             ok(match, "Expected 100.0, got %f\n", ptf.Y);
3849
3850             /* verify the result */
3851             ptf.Y = units_to_pixels(bounds.Height, gfx_unit, dpi);
3852             ptf.Y /= 100.0;
3853             match = fabs(100.0 - ptf.Y) <= 1.0;
3854 todo_wine
3855             ok(match, "Expected 100.0, got %f\n", ptf.Y);
3856
3857             /* bounds.width of 1 glyph: [margin]+[width]+[margin] */
3858             set_rect_empty(&rect);
3859             set_rect_empty(&bounds_1);
3860             status = GdipMeasureString(graphics, doubleW, 1, font, &rect, format, &bounds_1, NULL, NULL);
3861             expect(Ok, status);
3862             /* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
3863             set_rect_empty(&rect);
3864             set_rect_empty(&bounds_2);
3865             status = GdipMeasureString(graphics, doubleW, 2, font, &rect, format, &bounds_2, NULL, NULL);
3866             expect(Ok, status);
3867
3868             /* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
3869             margin = bounds_1.Width - bounds_2.Width / 2.0;
3870             /*trace("margin %f\n", margin);*/
3871             ok(margin > 0.0, "wrong margin %f\n", margin);
3872
3873             set_rect_empty(&rect);
3874             rect.Width = 320000.0;
3875             rect.Height = 320000.0;
3876             status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
3877             expect(Ok, status);
3878             set_rect_empty(&rect);
3879             status = GdipGetRegionBounds(region, graphics, &rect);
3880             expect(Ok, status);
3881             /*trace("region: %f,%f,%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);*/
3882             ok(rect.X > 0.0, "wrong rect.X %f\n", rect.X);
3883             expectf(0.0, rect.Y);
3884             match = fabs(1.0 - margin / rect.X) <= 0.05;
3885             ok(match, "Expected %f, got %f\n", margin, rect.X);
3886             match = fabs(1.0 - font_height / rect.Height) <= 0.1;
3887 todo_wine
3888             ok(match, "Expected %f, got %f\n", font_height, rect.Height);
3889             match = fabs(1.0 - bounds.Width / (rect.Width + margin * 2.0)) <= 0.05;
3890             ok(match, "Expected %f, got %f\n", bounds.Width, rect.Width + margin * 2.0);
3891         }
3892
3893         GdipDeleteFont(font);
3894     }
3895
3896 cleanup:
3897     status = GdipDeleteGraphics(graphics);
3898     expect(Ok, status);
3899     DeleteDC(hdc);
3900
3901     GdipDeleteFontFamily(family);
3902     GdipDeleteRegion(region);
3903     GdipDeleteStringFormat(format);
3904 }
3905
3906 static void test_measure_string(void)
3907 {
3908     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3909     static const WCHAR string[] = { 'A','0','1',0 };
3910     HDC hdc;
3911     GpStringFormat *format;
3912     GpGraphics *graphics;
3913     GpFontFamily *family;
3914     GpFont *font;
3915     GpStatus status;
3916     RectF bounds, rect;
3917     REAL width, height, width_1, width_2;
3918     int lines, glyphs;
3919
3920     status = GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &format);
3921     expect(Ok, status);
3922
3923     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3924     expect(Ok, status);
3925
3926     hdc = CreateCompatibleDC(0);
3927     status = GdipCreateFromHDC(hdc, &graphics);
3928
3929     status = GdipCreateFont(family, 20, FontStyleRegular, UnitPixel, &font);
3930     expect(Ok, status);
3931
3932     set_rect_empty(&rect);
3933     set_rect_empty(&bounds);
3934     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3935     expect(Ok, status);
3936     expect(3, glyphs);
3937     expect(1, lines);
3938     width = bounds.Width;
3939     height = bounds.Height;
3940
3941     set_rect_empty(&rect);
3942     rect.Height = height / 2.0;
3943     set_rect_empty(&bounds);
3944     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3945     expect(Ok, status);
3946     expect(3, glyphs);
3947     expect(1, lines);
3948     expectf(width, bounds.Width);
3949 todo_wine
3950     expectf(height / 2.0, bounds.Height);
3951
3952     set_rect_empty(&rect);
3953     set_rect_empty(&bounds);
3954     status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds, &glyphs, &lines);
3955     expect(Ok, status);
3956     expect(1, glyphs);
3957     expect(1, lines);
3958     ok(bounds.Width < width / 2.0, "width of 1 glyph is wrong\n");
3959     expectf(height, bounds.Height);
3960     width_1 = bounds.Width;
3961
3962     set_rect_empty(&rect);
3963     set_rect_empty(&bounds);
3964     status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds, &glyphs, &lines);
3965     expect(Ok, status);
3966     expect(2, glyphs);
3967     expect(1, lines);
3968     ok(bounds.Width < width, "width of 2 glyphs is wrong\n");
3969     ok(bounds.Width > width_1, "width of 2 glyphs is wrong\n");
3970     expectf(height, bounds.Height);
3971     width_2 = bounds.Width;
3972
3973     set_rect_empty(&rect);
3974     rect.Width = width / 2.0;
3975     set_rect_empty(&bounds);
3976     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3977     expect(Ok, status);
3978     expect(1, glyphs);
3979     expect(1, lines);
3980     expectf_(width_1, bounds.Width, 0.01);
3981     expectf(height, bounds.Height);
3982
3983     set_rect_empty(&rect);
3984     rect.Height = height;
3985     rect.Width = width - 0.05;
3986     set_rect_empty(&bounds);
3987     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3988     expect(Ok, status);
3989     expect(2, glyphs);
3990     expect(1, lines);
3991     expectf_(width_2, bounds.Width, 0.01);
3992     expectf(height, bounds.Height);
3993
3994     set_rect_empty(&rect);
3995     rect.Height = height;
3996     rect.Width = width_2 - 0.05;
3997     set_rect_empty(&bounds);
3998     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3999     expect(Ok, status);
4000     expect(1, glyphs);
4001     expect(1, lines);
4002     expectf_(width_1, bounds.Width, 0.01);
4003     expectf(height, bounds.Height);
4004
4005     status = GdipDeleteFont(font);
4006     expect(Ok, status);
4007
4008     status = GdipDeleteGraphics(graphics);
4009     expect(Ok, status);
4010     DeleteDC(hdc);
4011
4012     GdipDeleteFontFamily(family);
4013     GdipDeleteStringFormat(format);
4014 }
4015
4016 static void test_measured_extra_space(void)
4017 {
4018     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
4019     static const WCHAR string[2] = { 'W','W' };
4020     GpStringFormat *format;
4021     HDC hdc;
4022     GpGraphics *graphics;
4023     GpFontFamily *family;
4024     GpFont *font;
4025     GpStatus status;
4026     GpUnit gfx_unit, font_unit;
4027     RectF bounds_1, bounds_2, rect;
4028     REAL margin, font_size, dpi;
4029
4030     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
4031     expect(Ok, status);
4032
4033     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
4034     expect(Ok, status);
4035     hdc = CreateCompatibleDC(0);
4036     status = GdipCreateFromHDC(hdc, &graphics);
4037     expect(Ok, status);
4038
4039     status = GdipGetDpiX(graphics, &dpi);
4040     expect(Ok, status);
4041
4042     /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
4043     /* UnitPixel as a font base unit is not tested because it differs in behaviour */
4044     for (font_unit = 3; font_unit <= 6; font_unit++)
4045     {
4046         status = GdipCreateFont(family, 1234.0, FontStyleRegular, font_unit, &font);
4047         expect(Ok, status);
4048
4049         status = GdipGetFontSize(font, &font_size);
4050         expect(Ok, status);
4051         font_size = units_to_pixels(font_size, font_unit, dpi);
4052         /*trace("font size/6 = %f pixels\n", font_size / 6.0);*/
4053
4054         /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
4055         for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
4056         {
4057             status = GdipSetPageUnit(graphics, gfx_unit);
4058             expect(Ok, status);
4059
4060             /* bounds.width of 1 glyph: [margin]+[width]+[margin] */
4061             set_rect_empty(&rect);
4062             set_rect_empty(&bounds_1);
4063             status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds_1, NULL, NULL);
4064             expect(Ok, status);
4065             /* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
4066             set_rect_empty(&rect);
4067             set_rect_empty(&bounds_2);
4068             status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds_2, NULL, NULL);
4069             expect(Ok, status);
4070
4071             /* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
4072             margin = units_to_pixels(bounds_1.Width - bounds_2.Width / 2.0, gfx_unit, dpi);
4073             /*trace("margin %f pixels\n", margin);*/
4074             expectf_(font_size / 6.0, margin, font_size / 100.0);
4075         }
4076
4077         GdipDeleteFont(font);
4078     }
4079
4080     GdipDeleteGraphics(graphics);
4081     DeleteDC(hdc);
4082     GdipDeleteFontFamily(family);
4083     GdipDeleteStringFormat(format);
4084 }
4085
4086 static void test_alpha_hdc(void)
4087 {
4088     GpStatus status;
4089     HDC hdc;
4090     HBITMAP hbm, old_hbm;
4091     GpGraphics *graphics;
4092     ULONG *bits;
4093     BITMAPINFO bmi;
4094     GpRectF bounds;
4095
4096     hdc = CreateCompatibleDC(0);
4097     ok(hdc != NULL, "CreateCompatibleDC failed\n");
4098     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
4099     bmi.bmiHeader.biHeight = 5;
4100     bmi.bmiHeader.biWidth = 5;
4101     bmi.bmiHeader.biBitCount = 32;
4102     bmi.bmiHeader.biPlanes = 1;
4103     bmi.bmiHeader.biCompression = BI_RGB;
4104     bmi.bmiHeader.biClrUsed = 0;
4105
4106     hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
4107     ok(hbm != NULL, "CreateDIBSection failed\n");
4108
4109     old_hbm = SelectObject(hdc, hbm);
4110
4111     status = GdipCreateFromHDC(hdc, &graphics);
4112     expect(Ok, status);
4113
4114     status = GdipGetVisibleClipBounds(graphics, &bounds);
4115     expect(Ok, status);
4116     expectf(0.0, bounds.X);
4117     expectf(0.0, bounds.Y);
4118     expectf(5.0, bounds.Width);
4119     expectf(5.0, bounds.Height);
4120
4121     bits[0] = 0xdeadbeef;
4122
4123     status = GdipGraphicsClear(graphics, 0xffaaaaaa);
4124     expect(Ok, status);
4125
4126     expect(0xffaaaaaa, bits[0]);
4127
4128     SelectObject(hdc, old_hbm);
4129
4130     bits[0] = 0xdeadbeef;
4131
4132     status = GdipGraphicsClear(graphics, 0xffbbbbbb);
4133     expect(Ok, status);
4134
4135     todo_wine expect(0xffbbbbbb, bits[0]);
4136
4137     GdipDeleteGraphics(graphics);
4138
4139     DeleteObject(hbm);
4140     DeleteDC(hdc);
4141 }
4142
4143 START_TEST(graphics)
4144 {
4145     struct GdiplusStartupInput gdiplusStartupInput;
4146     ULONG_PTR gdiplusToken;
4147     WNDCLASSA class;
4148
4149     memset( &class, 0, sizeof(class) );
4150     class.lpszClassName = "gdiplus_test";
4151     class.style = CS_HREDRAW | CS_VREDRAW;
4152     class.lpfnWndProc = DefWindowProcA;
4153     class.hInstance = GetModuleHandleA(0);
4154     class.hIcon = LoadIcon(0, IDI_APPLICATION);
4155     class.hCursor = LoadCursor(NULL, IDC_ARROW);
4156     class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
4157     RegisterClassA( &class );
4158     hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4159                           CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 );
4160     ok(hwnd != NULL, "Expected window to be created\n");
4161
4162     gdiplusStartupInput.GdiplusVersion              = 1;
4163     gdiplusStartupInput.DebugEventCallback          = NULL;
4164     gdiplusStartupInput.SuppressBackgroundThread    = 0;
4165     gdiplusStartupInput.SuppressExternalCodecs      = 0;
4166
4167     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
4168
4169     test_measured_extra_space();
4170     test_measure_string();
4171     test_font_height_scaling();
4172     test_transform();
4173     test_GdipMeasureString();
4174     test_constructor_destructor();
4175     test_save_restore();
4176     test_GdipFillClosedCurve2();
4177     test_GdipFillClosedCurve2I();
4178     test_GdipDrawBezierI();
4179     test_GdipDrawArc();
4180     test_GdipDrawArcI();
4181     test_GdipDrawCurve();
4182     test_GdipDrawCurveI();
4183     test_GdipDrawCurve2();
4184     test_GdipDrawCurve2I();
4185     test_GdipDrawCurve3();
4186     test_GdipDrawCurve3I();
4187     test_GdipDrawLineI();
4188     test_GdipDrawLinesI();
4189     test_GdipDrawImagePointsRect();
4190     test_GdipFillClosedCurve();
4191     test_GdipFillClosedCurveI();
4192     test_GdipDrawString();
4193     test_GdipGetNearestColor();
4194     test_GdipGetVisibleClipBounds();
4195     test_GdipIsVisiblePoint();
4196     test_GdipIsVisibleRect();
4197     test_Get_Release_DC();
4198     test_BeginContainer2();
4199     test_transformpoints();
4200     test_get_set_clip();
4201     test_isempty();
4202     test_clear();
4203     test_textcontrast();
4204     test_fromMemoryBitmap();
4205     test_string_functions();
4206     test_get_set_interpolation();
4207     test_get_set_textrenderinghint();
4208     test_getdc_scaled();
4209     test_alpha_hdc();
4210
4211     GdiplusShutdown(gdiplusToken);
4212     DestroyWindow( hwnd );
4213 }