gdiplus: Add a test for extra space added by GdipMeasureString.
[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] = {0};
2949     BOOL region_isempty[4];
2950     int i;
2951     PointF position;
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.5;
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.5;
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     status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
3082     expect(Ok, status);
3083
3084     rc.Width = 100.0;
3085
3086     for (i=0; i<4; i++)
3087     {
3088         status = GdipCreateRegion(&regions[i]);
3089         expect(Ok, status);
3090     }
3091
3092     status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions);
3093     expect(InvalidParameter, status);
3094
3095     status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
3096     expect(InvalidParameter, status);
3097
3098     status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
3099     expect(InvalidParameter, status);
3100
3101     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
3102     expect(InvalidParameter, status);
3103
3104     if (0)
3105     {
3106         /* Crashes on Windows XP */
3107         status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
3108         expect(InvalidParameter, status);
3109     }
3110
3111     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL);
3112     expect(InvalidParameter, status);
3113
3114     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions);
3115     expect(InvalidParameter, status);
3116
3117     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions);
3118     expect(Ok, status);
3119
3120     for (i=0; i<4; i++)
3121     {
3122         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3123         expect(Ok, status);
3124     }
3125
3126     ok(!region_isempty[0], "region shouldn't be empty\n");
3127     ok(!region_isempty[1], "region shouldn't be empty\n");
3128     ok(!region_isempty[2], "region shouldn't be empty\n");
3129     ok(!region_isempty[3], "region shouldn't be empty\n");
3130
3131     /* Cut off everything after the first space, and the second line. */
3132     rc.Width = char_bounds.Width + char_width * 2.1;
3133     rc.Height = char_bounds.Height + char_height * 0.5;
3134
3135     status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3136     expect(Ok, status);
3137
3138     for (i=0; i<4; i++)
3139     {
3140         status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3141         expect(Ok, status);
3142     }
3143
3144     ok(!region_isempty[0], "region shouldn't be empty\n");
3145     ok(!region_isempty[1], "region shouldn't be empty\n");
3146     ok(region_isempty[2], "region should be empty\n");
3147     ok(!region_isempty[3], "region shouldn't be empty\n");
3148
3149     for (i=0; i<4; i++)
3150         GdipDeleteRegion(regions[i]);
3151
3152     status = GdipCreateMatrix(&identity);
3153     expect(Ok, status);
3154
3155     position.X = 0;
3156     position.Y = 0;
3157
3158     rc.X = 0;
3159     rc.Y = 0;
3160     rc.Width = 0;
3161     rc.Height = 0;
3162     status = GdipMeasureDriverString(NULL, teststring, 6, font, &position,
3163         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3164         identity, &rc);
3165     expect(InvalidParameter, status);
3166
3167     status = GdipMeasureDriverString(graphics, NULL, 6, font, &position,
3168         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3169         identity, &rc);
3170     expect(InvalidParameter, status);
3171
3172     status = GdipMeasureDriverString(graphics, teststring, 6, NULL, &position,
3173         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3174         identity, &rc);
3175     expect(InvalidParameter, status);
3176
3177     status = GdipMeasureDriverString(graphics, teststring, 6, font, NULL,
3178         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3179         identity, &rc);
3180     expect(InvalidParameter, status);
3181
3182     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3183         0x100, identity, &rc);
3184     expect(Ok, status);
3185
3186     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3187         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3188         NULL, &rc);
3189     expect(Ok, status);
3190
3191     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3192         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3193         identity, NULL);
3194     expect(InvalidParameter, status);
3195
3196     rc.X = 0;
3197     rc.Y = 0;
3198     rc.Width = 0;
3199     rc.Height = 0;
3200     status = GdipMeasureDriverString(graphics, teststring, 6, font, &position,
3201         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3202         identity, &rc);
3203     expect(Ok, status);
3204
3205     expectf(0.0, rc.X);
3206     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3207     ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width);
3208     ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y);
3209
3210     char_width = rc.Width;
3211     char_height = rc.Height;
3212
3213     rc.X = 0;
3214     rc.Y = 0;
3215     rc.Width = 0;
3216     rc.Height = 0;
3217     status = GdipMeasureDriverString(graphics, teststring, 4, font, &position,
3218         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3219         identity, &rc);
3220     expect(Ok, status);
3221
3222     expectf(0.0, rc.X);
3223     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3224     ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width);
3225     expectf(char_height, rc.Height);
3226
3227     rc.X = 0;
3228     rc.Y = 0;
3229     rc.Width = 0;
3230     rc.Height = 0;
3231     status = GdipMeasureDriverString(graphics, teststring2, 1, font, &position,
3232         DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3233         identity, &rc);
3234     expect(Ok, status);
3235
3236     expectf(rc.X, 0.0);
3237     ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3238     ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width);
3239     expectf(rc.Height, char_height);
3240
3241     GdipDeleteMatrix(identity);
3242     GdipDeleteStringFormat(format);
3243     GdipDeleteBrush(brush);
3244     GdipDeleteFont(font);
3245     GdipDeleteFontFamily(family);
3246     GdipDeleteGraphics(graphics);
3247
3248     ReleaseDC(hwnd, hdc);
3249 }
3250
3251 static void test_get_set_interpolation(void)
3252 {
3253     GpGraphics *graphics;
3254     HDC hdc = GetDC( hwnd );
3255     GpStatus status;
3256     InterpolationMode mode;
3257
3258     ok(hdc != NULL, "Expected HDC to be initialized\n");
3259     status = GdipCreateFromHDC(hdc, &graphics);
3260     expect(Ok, status);
3261     ok(graphics != NULL, "Expected graphics to be initialized\n");
3262
3263     status = GdipGetInterpolationMode(NULL, &mode);
3264     expect(InvalidParameter, status);
3265
3266     if (0)
3267     {
3268         /* Crashes on Windows XP */
3269         status = GdipGetInterpolationMode(graphics, NULL);
3270         expect(InvalidParameter, status);
3271     }
3272
3273     status = GdipSetInterpolationMode(NULL, InterpolationModeNearestNeighbor);
3274     expect(InvalidParameter, status);
3275
3276     /* out of range */
3277     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBicubic+1);
3278     expect(InvalidParameter, status);
3279
3280     status = GdipSetInterpolationMode(graphics, InterpolationModeInvalid);
3281     expect(InvalidParameter, status);
3282
3283     status = GdipGetInterpolationMode(graphics, &mode);
3284     expect(Ok, status);
3285     expect(InterpolationModeBilinear, mode);
3286
3287     status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3288     expect(Ok, status);
3289
3290     status = GdipGetInterpolationMode(graphics, &mode);
3291     expect(Ok, status);
3292     expect(InterpolationModeNearestNeighbor, mode);
3293
3294     status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
3295     expect(Ok, status);
3296
3297     status = GdipGetInterpolationMode(graphics, &mode);
3298     expect(Ok, status);
3299     expect(InterpolationModeBilinear, mode);
3300
3301     status = GdipSetInterpolationMode(graphics, InterpolationModeLowQuality);
3302     expect(Ok, status);
3303
3304     status = GdipGetInterpolationMode(graphics, &mode);
3305     expect(Ok, status);
3306     expect(InterpolationModeBilinear, mode);
3307
3308     status = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality);
3309     expect(Ok, status);
3310
3311     status = GdipGetInterpolationMode(graphics, &mode);
3312     expect(Ok, status);
3313     expect(InterpolationModeHighQualityBicubic, mode);
3314
3315     GdipDeleteGraphics(graphics);
3316
3317     ReleaseDC(hwnd, hdc);
3318 }
3319
3320 static void test_get_set_textrenderinghint(void)
3321 {
3322     GpGraphics *graphics;
3323     HDC hdc = GetDC( hwnd );
3324     GpStatus status;
3325     TextRenderingHint hint;
3326
3327     ok(hdc != NULL, "Expected HDC to be initialized\n");
3328     status = GdipCreateFromHDC(hdc, &graphics);
3329     expect(Ok, status);
3330     ok(graphics != NULL, "Expected graphics to be initialized\n");
3331
3332     status = GdipGetTextRenderingHint(NULL, &hint);
3333     expect(InvalidParameter, status);
3334
3335     status = GdipGetTextRenderingHint(graphics, NULL);
3336     expect(InvalidParameter, status);
3337
3338     status = GdipSetTextRenderingHint(NULL, TextRenderingHintAntiAlias);
3339     expect(InvalidParameter, status);
3340
3341     /* out of range */
3342     status = GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit+1);
3343     expect(InvalidParameter, status);
3344
3345     status = GdipGetTextRenderingHint(graphics, &hint);
3346     expect(Ok, status);
3347     expect(TextRenderingHintSystemDefault, hint);
3348
3349     status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
3350     expect(Ok, status);
3351
3352     status = GdipGetTextRenderingHint(graphics, &hint);
3353     expect(Ok, status);
3354     expect(TextRenderingHintSystemDefault, hint);
3355
3356     status = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAliasGridFit);
3357     expect(Ok, status);
3358
3359     status = GdipGetTextRenderingHint(graphics, &hint);
3360     expect(Ok, status);
3361     expect(TextRenderingHintAntiAliasGridFit, hint);
3362
3363     GdipDeleteGraphics(graphics);
3364
3365     ReleaseDC(hwnd, hdc);
3366 }
3367
3368 static void test_getdc_scaled(void)
3369 {
3370     GpStatus status;
3371     GpGraphics *graphics = NULL;
3372     GpBitmap *bitmap = NULL;
3373     HDC hdc=NULL;
3374     HBRUSH hbrush, holdbrush;
3375     ARGB color;
3376
3377     status = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, NULL, &bitmap);
3378     expect(Ok, status);
3379
3380     status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
3381     expect(Ok, status);
3382
3383     status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
3384     expect(Ok, status);
3385
3386     status = GdipGetDC(graphics, &hdc);
3387     expect(Ok, status);
3388     ok(hdc != NULL, "got NULL hdc\n");
3389
3390     hbrush = CreateSolidBrush(RGB(255, 0, 0));
3391
3392     holdbrush = SelectObject(hdc, hbrush);
3393
3394     Rectangle(hdc, 2, 2, 6, 6);
3395
3396     SelectObject(hdc, holdbrush);
3397
3398     DeleteObject(hbrush);
3399
3400     status = GdipReleaseDC(graphics, hdc);
3401     expect(Ok, status);
3402
3403     GdipDeleteGraphics(graphics);
3404
3405     status = GdipBitmapGetPixel(bitmap, 3, 3, &color);
3406     expect(Ok, status);
3407     expect(0xffff0000, color);
3408
3409     status = GdipBitmapGetPixel(bitmap, 8, 8, &color);
3410     expect(Ok, status);
3411     expect(0xff000000, color);
3412
3413     GdipDisposeImage((GpImage*)bitmap);
3414 }
3415
3416 static void test_GdipMeasureString(void)
3417 {
3418     static const struct test_data
3419     {
3420         REAL res_x, res_y, page_scale;
3421         GpUnit unit;
3422     } td[] =
3423     {
3424         { 200.0, 200.0, 1.0, UnitPixel }, /* base */
3425         { 200.0, 200.0, 2.0, UnitPixel },
3426         { 200.0, 200.0, 1.0, UnitDisplay },
3427         { 200.0, 200.0, 2.0, UnitDisplay },
3428         { 200.0, 200.0, 1.0, UnitInch },
3429         { 200.0, 200.0, 2.0, UnitInch },
3430         { 200.0, 600.0, 1.0, UnitPoint },
3431         { 200.0, 600.0, 2.0, UnitPoint },
3432         { 200.0, 600.0, 1.0, UnitDocument },
3433         { 200.0, 600.0, 2.0, UnitDocument },
3434         { 200.0, 600.0, 1.0, UnitMillimeter },
3435         { 200.0, 600.0, 2.0, UnitMillimeter },
3436         { 200.0, 600.0, 1.0, UnitDisplay },
3437         { 200.0, 600.0, 2.0, UnitDisplay },
3438         { 200.0, 600.0, 1.0, UnitPixel },
3439         { 200.0, 600.0, 2.0, UnitPixel },
3440     };
3441     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3442     static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3443     GpStatus status;
3444     GpGraphics *graphics;
3445     GpFontFamily *family;
3446     GpFont *font;
3447     GpStringFormat *format;
3448     RectF bounds, rc, empty_rc = { 0.0, 0.0, 0.0, 0.0 };
3449     REAL base_cx = 0, base_cy = 0, height;
3450     INT chars, lines;
3451     LOGFONTW lf;
3452     HDC display;
3453     UINT i, font_dpi;
3454     REAL font_to_pixel_scale, font_size;
3455     GpUnit font_unit, unit;
3456
3457     display = CreateCompatibleDC(0);
3458     ok(display != 0, "CreateCompatibleDC failed\n");
3459     font_dpi = GetDeviceCaps(display, LOGPIXELSY);
3460     DeleteDC(display);
3461
3462     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
3463     expect(Ok, status);
3464     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3465     expect(Ok, status);
3466
3467     font_to_pixel_scale = units_scale(UnitPoint, UnitPixel, font_dpi);
3468     trace("font to pixel, %u dpi => unit_scale %f\n", font_dpi, font_to_pixel_scale);
3469
3470     /* font size in pixels */
3471     status = GdipCreateFont(family, 100.0, FontStyleRegular, UnitPixel, &font);
3472     expect(Ok, status);
3473     status = GdipGetFontSize(font, &font_size);
3474     expect(Ok, status);
3475     expectf(100.0, font_size);
3476     status = GdipGetFontUnit(font, &font_unit);
3477     expect(Ok, status);
3478     expect(UnitPixel, font_unit);
3479
3480     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3481     {
3482         graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale);
3483
3484         lf.lfHeight = 0xdeadbeef;
3485         status = GdipGetLogFontW(font, graphics, &lf);
3486         expect(Ok, status);
3487         height = units_to_pixels(font_size, td[i].unit, td[i].res_y);
3488         if (td[i].unit != UnitDisplay)
3489             height *= td[i].page_scale;
3490         ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3491            i, (LONG)(height + 0.5), height, lf.lfHeight);
3492
3493         height = font_size * font_to_pixel_scale;
3494
3495         rc = empty_rc;
3496         bounds = empty_rc;
3497         status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3498         expect(Ok, status);
3499
3500         if (i == 0)
3501         {
3502             base_cx = bounds.Width;
3503             base_cy = bounds.Height;
3504         }
3505
3506         expectf(0.0, bounds.X);
3507         expectf(0.0, bounds.Y);
3508         expectf_(height, bounds.Height, height / 100.0);
3509         expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
3510         expect(7, chars);
3511         expect(1, lines);
3512
3513         /* make sure it really fits */
3514         bounds.Width += 1.0;
3515         bounds.Height += 1.0;
3516         rc = bounds;
3517         rc.X = 50.0;
3518         rc.Y = 50.0;
3519         bounds = empty_rc;
3520         status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3521         expect(Ok, status);
3522         expectf(50.0, bounds.X);
3523         expectf(50.0, bounds.Y);
3524         expectf_(height, bounds.Height, height / 100.0);
3525         expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
3526         expect(7, chars);
3527         expect(1, lines);
3528
3529         status = GdipDeleteGraphics(graphics);
3530         expect(Ok, status);
3531     }
3532
3533     GdipDeleteFont(font);
3534
3535     /* font size in logical units */
3536     /* UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3537     for (unit = 3; unit <= 6; unit++)
3538     {
3539         /* create a font which final height is 100.0 pixels with 200 dpi device */
3540         height = pixels_to_units(100.0 / font_to_pixel_scale, unit, 200.0);
3541         status = GdipCreateFont(family, height, FontStyleRegular, unit, &font);
3542         expect(Ok, status);
3543         status = GdipGetFontSize(font, &font_size);
3544         expect(Ok, status);
3545         expectf(height, font_size);
3546         status = GdipGetFontUnit(font, &font_unit);
3547         expect(Ok, status);
3548         expect(unit, font_unit);
3549
3550         for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3551         {
3552             REAL unit_scale;
3553
3554             graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale);
3555
3556             lf.lfHeight = 0xdeadbeef;
3557             status = GdipGetLogFontW(font, graphics, &lf);
3558             expect(Ok, status);
3559             if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3560                 height = units_to_pixels(font_size, font_unit, td[i].res_x);
3561             else
3562                 height = units_to_pixels(font_size, font_unit, td[i].res_y);
3563             /*trace("%.1f font units = %f pixels with %.1f dpi, page_scale %.1f\n", font_size, height, td[i].res_y, td[i].page_scale);*/
3564             ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3565                i, (LONG)(height + 0.5), height, lf.lfHeight);
3566
3567             if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3568                 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_x);
3569             else
3570                 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_y);
3571             /*trace("%u: %d to %d, %.1f dpi => unit_scale %f\n", i, font_unit, td[i].unit, td[i].res_y, unit_scale);*/
3572             height = font_size * font_to_pixel_scale * unit_scale;
3573             if (td[i].unit != UnitDisplay)
3574                 height /= td[i].page_scale;
3575             /*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);*/
3576
3577             rc = empty_rc;
3578             bounds = empty_rc;
3579             status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3580             expect(Ok, status);
3581
3582             if (i == 0)
3583             {
3584                 base_cx = bounds.Width;
3585                 base_cy = bounds.Height;
3586             }
3587
3588             expectf(0.0, bounds.X);
3589             expectf(0.0, bounds.Y);
3590             expectf_(height, bounds.Height, height / 85.0);
3591             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
3592             expect(7, chars);
3593             expect(1, lines);
3594
3595             /* make sure it really fits */
3596             bounds.Width += 1.0;
3597             bounds.Height += 1.0;
3598             rc = bounds;
3599             rc.X = 50.0;
3600             rc.Y = 50.0;
3601             bounds = empty_rc;
3602             status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3603             expect(Ok, status);
3604             expectf(50.0, bounds.X);
3605             expectf(50.0, bounds.Y);
3606             expectf_(height, bounds.Height, height / 85.0);
3607             expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.05);
3608             expect(7, chars);
3609             expect(1, lines);
3610
3611             /* verify the result */
3612             height = units_to_pixels(bounds.Height, td[i].unit, td[i].res_x);
3613             if (td[i].unit != UnitDisplay)
3614                 height *= td[i].page_scale;
3615             /*trace("%u: unit %u, %.1fx%.1f dpi, scale %.1f, height %f, pixels %f\n",
3616                   i, td[i].unit, td[i].res_x, td[i].res_y, td[i].page_scale, bounds.Height, height);*/
3617             expectf_(100.0, height, 1.1);
3618
3619             status = GdipDeleteGraphics(graphics);
3620             expect(Ok, status);
3621         }
3622
3623         GdipDeleteFont(font);
3624     }
3625
3626     GdipDeleteFontFamily(family);
3627     GdipDeleteStringFormat(format);
3628 }
3629
3630 static void test_transform(void)
3631 {
3632     static const struct test_data
3633     {
3634         REAL res_x, res_y, scale;
3635         GpUnit unit;
3636         GpPointF in[2], out[2];
3637     } td[] =
3638     {
3639         { 96.0, 96.0, 1.0, UnitPixel,
3640           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3641         { 96.0, 96.0, 1.0, UnitDisplay,
3642           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3643         { 96.0, 96.0, 1.0, UnitInch,
3644           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 9600.0, 0.0 }, { 0.0, 9600.0 } } },
3645         { 123.0, 456.0, 1.0, UnitPoint,
3646           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 170.833313, 0.0 }, { 0.0, 633.333252 } } },
3647         { 123.0, 456.0, 1.0, UnitDocument,
3648           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 40.999996, 0.0 }, { 0.0, 151.999985 } } },
3649         { 123.0, 456.0, 2.0, UnitMillimeter,
3650           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 968.503845, 0.0 }, { 0.0, 3590.550781 } } },
3651         { 196.0, 296.0, 1.0, UnitDisplay,
3652           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3653         { 196.0, 296.0, 1.0, UnitPixel,
3654           { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3655     };
3656     GpStatus status;
3657     GpGraphics *graphics;
3658     GpPointF ptf[2];
3659     UINT i;
3660
3661     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3662     {
3663         graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].scale);
3664         ptf[0].X = td[i].in[0].X;
3665         ptf[0].Y = td[i].in[0].Y;
3666         ptf[1].X = td[i].in[1].X;
3667         ptf[1].Y = td[i].in[1].Y;
3668         status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
3669         expect(Ok, status);
3670         expectf(td[i].out[0].X, ptf[0].X);
3671         expectf(td[i].out[0].Y, ptf[0].Y);
3672         expectf(td[i].out[1].X, ptf[1].X);
3673         expectf(td[i].out[1].Y, ptf[1].Y);
3674         status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
3675         expect(Ok, status);
3676         expectf(td[i].in[0].X, ptf[0].X);
3677         expectf(td[i].in[0].Y, ptf[0].Y);
3678         expectf(td[i].in[1].X, ptf[1].X);
3679         expectf(td[i].in[1].Y, ptf[1].Y);
3680         status = GdipDeleteGraphics(graphics);
3681         expect(Ok, status);
3682     }
3683 }
3684
3685 /* Many people on the net ask why there is so much difference in rendered
3686  * text height between gdiplus and gdi32, this test suggests an answer to
3687  * that question. Important: this test assumes that font dpi == device dpi.
3688  */
3689 static void test_font_height_scaling(void)
3690 {
3691     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3692     static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3693     HDC hdc;
3694     GpStringFormat *format;
3695     GpGraphics *graphics;
3696     GpFontFamily *family;
3697     GpFont *font;
3698     GpStatus status;
3699     RectF bounds, rect;
3700     REAL height, dpi;
3701     PointF ptf;
3702     GpUnit gfx_unit, font_unit;
3703
3704     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
3705     expect(Ok, status);
3706     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3707     expect(Ok, status);
3708
3709     hdc = CreateCompatibleDC(0);
3710     status = GdipCreateFromHDC(hdc, &graphics);
3711
3712     status = GdipGetDpiY(graphics, &dpi);
3713     expect(Ok, status);
3714
3715     /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3716     /* UnitPixel as a font base unit is not tested because it drastically
3717        differs in behaviour */
3718     for (font_unit = 3; font_unit <= 6; font_unit++)
3719     {
3720         /* There is a bug somewhere in native gdiplus that leads
3721          * to extra conversion from points to pixels, so in order
3722          * to get a 100 pixel text height it's needed to convert
3723          * 100 pixels to points, and only then convert the result
3724          * to desired units. The scale factor is 1.333333 at 96 dpi!
3725          * Perhaps an implementor took name of GdipTransformPoints
3726          * directly and assumed that it takes value in *points*?
3727          */
3728         status = GdipSetPageUnit(graphics, UnitPoint);
3729         expect(Ok, status);
3730         ptf.X = 0;
3731         ptf.Y = 100.0;
3732         status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3733         expect(Ok, status);
3734         trace("100.0 pixels, %.1f dpi => %f points\n", dpi, ptf.Y);
3735         status = GdipSetPageUnit(graphics, font_unit);
3736         expect(Ok, status);
3737         status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3738         expect(Ok, status);
3739         height = ptf.Y;
3740         trace("height %f units\n", height);
3741         status = GdipCreateFont(family, height, FontStyleRegular, font_unit, &font);
3742         expect(Ok, status);
3743
3744         /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3745         for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
3746         {
3747             int match;
3748
3749             status = GdipSetPageUnit(graphics, gfx_unit);
3750             expect(Ok, status);
3751
3752             rect.X = 0.0;
3753             rect.Y = 0.0;
3754             rect.Width = 0;
3755             rect.Height = 0;
3756             bounds.X = 0.0;
3757             bounds.Y = 0.0;
3758             bounds.Width = 0;
3759             bounds.Height = 0;
3760             status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
3761             expect(Ok, status);
3762
3763             ptf.X = 0;
3764             ptf.Y = bounds.Height;
3765             status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &ptf, 1);
3766             expect(Ok, status);
3767             match = fabs(100.0 - ptf.Y) <= 1.0;
3768             ok(match || broken(!match) /* before win7 */, "Expected 100.0, got %f\n", ptf.Y);
3769
3770             /* verify the result */
3771             ptf.Y = units_to_pixels(bounds.Height, gfx_unit, dpi);
3772             match = fabs(100.0 - ptf.Y) <= 1.1;
3773             ok(match || broken(!match) /* before win7 */, "Expected 100.0, got %f\n", ptf.Y);
3774         }
3775     }
3776
3777     status = GdipDeleteGraphics(graphics);
3778     expect(Ok, status);
3779     DeleteDC(hdc);
3780
3781     GdipDeleteFontFamily(family);
3782     GdipDeleteStringFormat(format);
3783 }
3784
3785 static void test_measure_string(void)
3786 {
3787     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3788     static const WCHAR string[] = { 'A','0','1',0 };
3789     HDC hdc;
3790     GpStringFormat *format;
3791     GpGraphics *graphics;
3792     GpFontFamily *family;
3793     GpFont *font;
3794     GpStatus status;
3795     RectF bounds, rect;
3796     REAL width, height, width_1, width_2;
3797     int lines, glyphs;
3798
3799     status = GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &format);
3800     expect(Ok, status);
3801
3802     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3803     expect(Ok, status);
3804
3805     hdc = CreateCompatibleDC(0);
3806     status = GdipCreateFromHDC(hdc, &graphics);
3807
3808     status = GdipCreateFont(family, 20, FontStyleRegular, UnitPixel, &font);
3809     expect(Ok, status);
3810
3811     set_rect_empty(&rect);
3812     set_rect_empty(&bounds);
3813     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3814     expect(Ok, status);
3815     expect(3, glyphs);
3816     expect(1, lines);
3817     width = bounds.Width;
3818     height = bounds.Height;
3819
3820     set_rect_empty(&rect);
3821     rect.Height = height / 2.0;
3822     set_rect_empty(&bounds);
3823     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3824     expect(Ok, status);
3825     expect(3, glyphs);
3826     expect(1, lines);
3827     expectf(width, bounds.Width);
3828 todo_wine
3829     expectf(height / 2.0, bounds.Height);
3830
3831     set_rect_empty(&rect);
3832     set_rect_empty(&bounds);
3833     status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds, &glyphs, &lines);
3834     expect(Ok, status);
3835     expect(1, glyphs);
3836     expect(1, lines);
3837     ok(bounds.Width < width / 2.0, "width of 1 glyph is wrong\n");
3838     expectf(height, bounds.Height);
3839     width_1 = bounds.Width;
3840
3841     set_rect_empty(&rect);
3842     set_rect_empty(&bounds);
3843     status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds, &glyphs, &lines);
3844     expect(Ok, status);
3845     expect(2, glyphs);
3846     expect(1, lines);
3847     ok(bounds.Width < width, "width of 2 glyphs is wrong\n");
3848     ok(bounds.Width > width_1, "width of 2 glyphs is wrong\n");
3849     expectf(height, bounds.Height);
3850     width_2 = bounds.Width;
3851
3852     set_rect_empty(&rect);
3853     rect.Width = width / 2.0;
3854     set_rect_empty(&bounds);
3855     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3856     expect(Ok, status);
3857     expect(1, glyphs);
3858     expect(1, lines);
3859     expectf_(width_1, bounds.Width, 0.01);
3860     expectf(height, bounds.Height);
3861
3862     set_rect_empty(&rect);
3863     rect.Height = height;
3864     rect.Width = width - 0.05;
3865     set_rect_empty(&bounds);
3866     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3867     expect(Ok, status);
3868     expect(2, glyphs);
3869     expect(1, lines);
3870     expectf_(width_2, bounds.Width, 0.01);
3871     expectf(height, bounds.Height);
3872
3873     set_rect_empty(&rect);
3874     rect.Height = height;
3875     rect.Width = width_2 - 0.05;
3876     set_rect_empty(&bounds);
3877     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3878     expect(Ok, status);
3879     expect(1, glyphs);
3880     expect(1, lines);
3881     expectf_(width_1, bounds.Width, 0.01);
3882     expectf(height, bounds.Height);
3883
3884     status = GdipDeleteFont(font);
3885     expect(Ok, status);
3886
3887     status = GdipDeleteGraphics(graphics);
3888     expect(Ok, status);
3889     DeleteDC(hdc);
3890
3891     GdipDeleteFontFamily(family);
3892     GdipDeleteStringFormat(format);
3893 }
3894
3895 static void test_measured_extra_space(void)
3896 {
3897     static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3898     static const WCHAR string[2] = { 'W','W' };
3899     GpStringFormat *format;
3900     HDC hdc;
3901     GpGraphics *graphics;
3902     GpFontFamily *family;
3903     GpFont *font;
3904     GpStatus status;
3905     GpUnit gfx_unit, font_unit;
3906     RectF bounds_1, bounds_2, rect;
3907     REAL margin, font_size, dpi;
3908
3909     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
3910     expect(Ok, status);
3911
3912     status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3913     expect(Ok, status);
3914     hdc = CreateCompatibleDC(0);
3915     status = GdipCreateFromHDC(hdc, &graphics);
3916     expect(Ok, status);
3917
3918     status = GdipGetDpiX(graphics, &dpi);
3919     expect(Ok, status);
3920
3921     /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3922     /* UnitPixel as a font base unit is not tested because it differs in behaviour */
3923     for (font_unit = 3; font_unit <= 6; font_unit++)
3924     {
3925         status = GdipCreateFont(family, 1234.0, FontStyleRegular, font_unit, &font);
3926         expect(Ok, status);
3927
3928         status = GdipGetFontSize(font, &font_size);
3929         expect(Ok, status);
3930         font_size = units_to_pixels(font_size, font_unit, dpi);
3931         /*trace("font size/6 = %f pixels\n", font_size / 6.0);*/
3932
3933         /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3934         for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
3935         {
3936             status = GdipSetPageUnit(graphics, gfx_unit);
3937             expect(Ok, status);
3938
3939             /* bounds.width of 1 glyph: [margin]+[width]+[margin] */
3940             set_rect_empty(&rect);
3941             set_rect_empty(&bounds_1);
3942             status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds_1, NULL, NULL);
3943             expect(Ok, status);
3944             /* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
3945             set_rect_empty(&rect);
3946             set_rect_empty(&bounds_2);
3947             status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds_2, NULL, NULL);
3948             expect(Ok, status);
3949
3950             /* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
3951             margin = units_to_pixels(bounds_1.Width - bounds_2.Width / 2.0, gfx_unit, dpi);
3952             /*trace("margin %f pixels\n", margin);*/
3953 todo_wine
3954             expectf_(font_size / 6.0, margin, font_size / 100.0);
3955         }
3956
3957         GdipDeleteFont(font);
3958     }
3959
3960     GdipDeleteGraphics(graphics);
3961     DeleteDC(hdc);
3962     GdipDeleteFontFamily(family);
3963     GdipDeleteStringFormat(format);
3964 }
3965
3966 START_TEST(graphics)
3967 {
3968     struct GdiplusStartupInput gdiplusStartupInput;
3969     ULONG_PTR gdiplusToken;
3970     WNDCLASSA class;
3971
3972     memset( &class, 0, sizeof(class) );
3973     class.lpszClassName = "gdiplus_test";
3974     class.style = CS_HREDRAW | CS_VREDRAW;
3975     class.lpfnWndProc = DefWindowProcA;
3976     class.hInstance = GetModuleHandleA(0);
3977     class.hIcon = LoadIcon(0, IDI_APPLICATION);
3978     class.hCursor = LoadCursor(NULL, IDC_ARROW);
3979     class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
3980     RegisterClassA( &class );
3981     hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3982                           CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 );
3983     ok(hwnd != NULL, "Expected window to be created\n");
3984
3985     gdiplusStartupInput.GdiplusVersion              = 1;
3986     gdiplusStartupInput.DebugEventCallback          = NULL;
3987     gdiplusStartupInput.SuppressBackgroundThread    = 0;
3988     gdiplusStartupInput.SuppressExternalCodecs      = 0;
3989
3990     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
3991
3992     test_measured_extra_space();
3993     test_measure_string();
3994     test_font_height_scaling();
3995     test_transform();
3996     test_GdipMeasureString();
3997     test_constructor_destructor();
3998     test_save_restore();
3999     test_GdipFillClosedCurve2();
4000     test_GdipFillClosedCurve2I();
4001     test_GdipDrawBezierI();
4002     test_GdipDrawArc();
4003     test_GdipDrawArcI();
4004     test_GdipDrawCurve();
4005     test_GdipDrawCurveI();
4006     test_GdipDrawCurve2();
4007     test_GdipDrawCurve2I();
4008     test_GdipDrawCurve3();
4009     test_GdipDrawCurve3I();
4010     test_GdipDrawLineI();
4011     test_GdipDrawLinesI();
4012     test_GdipDrawImagePointsRect();
4013     test_GdipFillClosedCurve();
4014     test_GdipFillClosedCurveI();
4015     test_GdipDrawString();
4016     test_GdipGetNearestColor();
4017     test_GdipGetVisibleClipBounds();
4018     test_GdipIsVisiblePoint();
4019     test_GdipIsVisibleRect();
4020     test_Get_Release_DC();
4021     test_BeginContainer2();
4022     test_transformpoints();
4023     test_get_set_clip();
4024     test_isempty();
4025     test_clear();
4026     test_textcontrast();
4027     test_fromMemoryBitmap();
4028     test_string_functions();
4029     test_get_set_interpolation();
4030     test_get_set_textrenderinghint();
4031     test_getdc_scaled();
4032
4033     GdiplusShutdown(gdiplusToken);
4034     DestroyWindow( hwnd );
4035 }