gdiplus: Fix graphics bounds for memory DC's.
[wine] / dlls / gdiplus / tests / font.c
1 /*
2  * Unit test suite for fonts
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
24 #include "windows.h"
25 #include "gdiplus.h"
26 #include "wine/test.h"
27
28 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
29 #define expect_(expected, got, precision) ok(abs((expected) - (got)) <= (precision), "Expected %d, got %d\n", (expected), (got))
30 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
31 #define expectf(expected, got) expectf_((expected), (got), 0.001)
32
33 static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'};
34 static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
35 static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
36 static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
37 static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
38 static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
39 static const WCHAR LiberationSerif[] = {'L','i','b','e','r','a','t','i','o','n',' ','S','e','r','i','f',0};
40
41 static void set_rect_empty(RectF *rc)
42 {
43     rc->X = 0.0;
44     rc->Y = 0.0;
45     rc->Width = 0.0;
46     rc->Height = 0.0;
47 }
48
49 static void test_createfont(void)
50 {
51     GpFontFamily* fontfamily = NULL, *fontfamily2;
52     GpFont* font = NULL;
53     GpStatus stat;
54     Unit unit;
55     UINT i;
56     REAL size;
57     WCHAR familyname[LF_FACESIZE];
58
59     stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily);
60     expect (FontFamilyNotFound, stat);
61     stat = GdipDeleteFont(font);
62     expect (InvalidParameter, stat);
63     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
64     expect (Ok, stat);
65     stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
66     expect (Ok, stat);
67     stat = GdipGetFontUnit (font, &unit);
68     expect (Ok, stat);
69     expect (UnitPoint, unit);
70
71     stat = GdipGetFamily(font, &fontfamily2);
72     expect(Ok, stat);
73     stat = GdipGetFamilyName(fontfamily2, familyname, 0);
74     expect(Ok, stat);
75     ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
76             wine_dbgstr_w(familyname));
77     stat = GdipDeleteFontFamily(fontfamily2);
78     expect(Ok, stat);
79
80     /* Test to see if returned size is based on unit (its not) */
81     GdipGetFontSize(font, &size);
82     ok (size == 12, "Expected 12, got %f\n", size);
83     GdipDeleteFont(font);
84
85     /* Make sure everything is converted correctly for all Units */
86     for (i = UnitWorld; i <=UnitMillimeter; i++)
87     {
88         if (i == UnitDisplay) continue; /* Crashes WindowsXP, wtf? */
89         GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font);
90         GdipGetFontSize (font, &size);
91         ok (size == 24, "Expected 24, got %f (with unit: %d)\n", size, i);
92         GdipGetFontUnit (font, &unit);
93         expect (i, unit);
94         GdipDeleteFont(font);
95     }
96
97     GdipDeleteFontFamily(fontfamily);
98 }
99
100 static void test_logfont(void)
101 {
102     LOGFONTA lfa, lfa2;
103     GpFont *font;
104     GpFontFamily *family;
105     GpStatus stat;
106     GpGraphics *graphics;
107     HDC hdc = GetDC(0);
108     INT style;
109     REAL rval;
110     UINT16 em_height, line_spacing;
111     Unit unit;
112
113     GdipCreateFromHDC(hdc, &graphics);
114
115     memset(&lfa, 0, sizeof(LOGFONTA));
116     memset(&lfa2, 0xff, sizeof(LOGFONTA));
117     lstrcpyA(lfa.lfFaceName, "Tahoma");
118
119     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
120     expect(Ok, stat);
121     stat = GdipGetLogFontA(font, graphics, &lfa2);
122     expect(Ok, stat);
123
124     ok(lfa2.lfHeight < 0, "Expected negative height\n");
125     expect(0, lfa2.lfWidth);
126     expect(0, lfa2.lfEscapement);
127     expect(0, lfa2.lfOrientation);
128     ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
129     expect(0, lfa2.lfItalic);
130     expect(0, lfa2.lfUnderline);
131     expect(0, lfa2.lfStrikeOut);
132     ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
133         "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
134     expect(0, lfa2.lfOutPrecision);
135     expect(0, lfa2.lfClipPrecision);
136     expect(0, lfa2.lfQuality);
137     expect(0, lfa2.lfPitchAndFamily);
138
139     GdipDeleteFont(font);
140
141     memset(&lfa, 0, sizeof(LOGFONTA));
142     lfa.lfHeight = 25;
143     lfa.lfWidth = 25;
144     lfa.lfEscapement = lfa.lfOrientation = 50;
145     lfa.lfItalic = lfa.lfUnderline = lfa.lfStrikeOut = TRUE;
146
147     memset(&lfa2, 0xff, sizeof(LOGFONTA));
148     lstrcpyA(lfa.lfFaceName, "Tahoma");
149
150     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
151     expect(Ok, stat);
152     stat = GdipGetLogFontA(font, graphics, &lfa2);
153     expect(Ok, stat);
154
155     ok(lfa2.lfHeight < 0, "Expected negative height\n");
156     expect(0, lfa2.lfWidth);
157     expect(0, lfa2.lfEscapement);
158     expect(0, lfa2.lfOrientation);
159     ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
160     expect(TRUE, lfa2.lfItalic);
161     expect(TRUE, lfa2.lfUnderline);
162     expect(TRUE, lfa2.lfStrikeOut);
163     ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
164         "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
165     expect(0, lfa2.lfOutPrecision);
166     expect(0, lfa2.lfClipPrecision);
167     expect(0, lfa2.lfQuality);
168     expect(0, lfa2.lfPitchAndFamily);
169
170     stat = GdipGetFontStyle(font, &style);
171     expect(Ok, stat);
172     ok (style == (FontStyleItalic | FontStyleUnderline | FontStyleStrikeout),
173             "Expected , got %d\n", style);
174
175     stat = GdipGetFontUnit(font, &unit);
176     expect(Ok, stat);
177     expect(UnitWorld, unit);
178
179     stat = GdipGetFontHeight(font, graphics, &rval);
180     expect(Ok, stat);
181     expectf(25.347656, rval);
182     stat = GdipGetFontSize(font, &rval);
183     expect(Ok, stat);
184     expectf(21.0, rval);
185
186     stat = GdipGetFamily(font, &family);
187     expect(Ok, stat);
188     stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
189     expect(Ok, stat);
190     expect(2048, em_height);
191     stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
192     expect(Ok, stat);
193     expect(2472, line_spacing);
194     GdipDeleteFontFamily(family);
195
196     GdipDeleteFont(font);
197
198     memset(&lfa, 0, sizeof(lfa));
199     lfa.lfHeight = -25;
200     lstrcpyA(lfa.lfFaceName, "Tahoma");
201     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
202     expect(Ok, stat);
203     memset(&lfa2, 0xff, sizeof(lfa2));
204     stat = GdipGetLogFontA(font, graphics, &lfa2);
205     expect(Ok, stat);
206     expect(lfa.lfHeight, lfa2.lfHeight);
207
208     stat = GdipGetFontUnit(font, &unit);
209     expect(Ok, stat);
210     expect(UnitWorld, unit);
211
212     stat = GdipGetFontHeight(font, graphics, &rval);
213     expect(Ok, stat);
214     expectf(30.175781, rval);
215     stat = GdipGetFontSize(font, &rval);
216     expect(Ok, stat);
217     expectf(25.0, rval);
218
219     stat = GdipGetFamily(font, &family);
220     expect(Ok, stat);
221     stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
222     expect(Ok, stat);
223     expect(2048, em_height);
224     stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
225     expect(Ok, stat);
226     expect(2472, line_spacing);
227     GdipDeleteFontFamily(family);
228
229     GdipDeleteFont(font);
230
231     GdipDeleteGraphics(graphics);
232     ReleaseDC(0, hdc);
233 }
234
235 static void test_fontfamily (void)
236 {
237     GpFontFamily *family, *clonedFontFamily;
238     WCHAR itsName[LF_FACESIZE];
239     GpStatus stat;
240
241     /* FontFamily cannot be NULL */
242     stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
243     expect (InvalidParameter, stat);
244
245     /* FontFamily must be able to actually find the family.
246      * If it can't, any subsequent calls should fail.
247      */
248     stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
249     expect (FontFamilyNotFound, stat);
250
251     /* Bitmap fonts are not found */
252     stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
253     expect (FontFamilyNotFound, stat);
254     if(stat == Ok) GdipDeleteFontFamily(family);
255
256     stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
257     expect (Ok, stat);
258
259     stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
260     expect (Ok, stat);
261     expect (0, lstrcmpiW(itsName, Tahoma));
262
263     if (0)
264     {
265         /* Crashes on Windows XP SP2, Vista, and so Wine as well */
266         stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL);
267         expect (Ok, stat);
268     }
269
270     /* Make sure we don't read old data */
271     ZeroMemory (itsName, sizeof(itsName));
272     stat = GdipCloneFontFamily(family, &clonedFontFamily);
273     expect (Ok, stat);
274     GdipDeleteFontFamily(family);
275     stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
276     expect(Ok, stat);
277     expect(0, lstrcmpiW(itsName, Tahoma));
278
279     GdipDeleteFontFamily(clonedFontFamily);
280 }
281
282 static void test_fontfamily_properties (void)
283 {
284     GpFontFamily* FontFamily = NULL;
285     GpStatus stat;
286     UINT16 result = 0;
287
288     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
289     expect(Ok, stat);
290
291     stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
292     expect(Ok, stat);
293     ok (result == 2472, "Expected 2472, got %d\n", result);
294     result = 0;
295     stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
296     expect(Ok, stat);
297     ok(result == 2048, "Expected 2048, got %d\n", result);
298     result = 0;
299     stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
300     expect(Ok, stat);
301     ok(result == 2049, "Expected 2049, got %d\n", result);
302     result = 0;
303     stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
304     expect(Ok, stat);
305     ok(result == 423, "Expected 423, got %d\n", result);
306     GdipDeleteFontFamily(FontFamily);
307
308     stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
309     if(stat == FontFamilyNotFound)
310         skip("Times New Roman not installed\n");
311     else
312     {
313         result = 0;
314         stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
315         expect(Ok, stat);
316         ok(result == 2355, "Expected 2355, got %d\n", result);
317         result = 0;
318         stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
319         expect(Ok, stat);
320         ok(result == 2048, "Expected 2048, got %d\n", result);
321         result = 0;
322         stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
323         expect(Ok, stat);
324         ok(result == 1825, "Expected 1825, got %d\n", result);
325         result = 0;
326         stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
327         expect(Ok, stat);
328         ok(result == 443, "Expected 443 got %d\n", result);
329         GdipDeleteFontFamily(FontFamily);
330     }
331 }
332
333 static void check_family(const char* context, GpFontFamily *family, WCHAR *name)
334 {
335     GpStatus stat;
336     GpFont* font;
337
338     *name = 0;
339     stat = GdipGetFamilyName(family, name, LANG_NEUTRAL);
340     ok(stat == Ok, "could not get the %s family name: %.8x\n", context, stat);
341
342     stat = GdipCreateFont(family, 12, FontStyleRegular, UnitPixel, &font);
343     ok(stat == Ok, "could not create a font for the %s family: %.8x\n", context, stat);
344     if (stat == Ok)
345     {
346         stat = GdipDeleteFont(font);
347         ok(stat == Ok, "could not delete the %s family font: %.8x\n", context, stat);
348     }
349
350     stat = GdipDeleteFontFamily(family);
351     ok(stat == Ok, "could not delete the %s family: %.8x\n", context, stat);
352 }
353
354 static void test_getgenerics (void)
355 {
356     GpStatus stat;
357     GpFontFamily *family;
358     WCHAR sansname[LF_FACESIZE], serifname[LF_FACESIZE], mononame[LF_FACESIZE];
359     int missingfonts = 0;
360
361     stat = GdipGetGenericFontFamilySansSerif(&family);
362     expect (Ok, stat);
363     if (stat == FontFamilyNotFound)
364         missingfonts = 1;
365     else
366         check_family("Sans Serif", family, sansname);
367
368     stat = GdipGetGenericFontFamilySerif(&family);
369     expect (Ok, stat);
370     if (stat == FontFamilyNotFound)
371         missingfonts = 1;
372     else
373         check_family("Serif", family, serifname);
374
375     stat = GdipGetGenericFontFamilyMonospace(&family);
376     expect (Ok, stat);
377     if (stat == FontFamilyNotFound)
378         missingfonts = 1;
379     else
380         check_family("Monospace", family, mononame);
381
382     if (missingfonts && strcmp(winetest_platform, "wine") == 0)
383         trace("You may need to install either the Microsoft Web Fonts or the Liberation Fonts\n");
384
385     /* Check that the family names are all different */
386     ok(lstrcmpiW(sansname, serifname) != 0, "Sans Serif and Serif families should be different: %s\n", wine_dbgstr_w(sansname));
387     ok(lstrcmpiW(sansname, mononame) != 0, "Sans Serif and Monospace families should be different: %s\n", wine_dbgstr_w(sansname));
388     ok(lstrcmpiW(serifname, mononame) != 0, "Serif and Monospace families should be different: %s\n", wine_dbgstr_w(serifname));
389 }
390
391 static void test_installedfonts (void)
392 {
393     GpStatus stat;
394     GpFontCollection* collection=NULL;
395
396     stat = GdipNewInstalledFontCollection(NULL);
397     expect (InvalidParameter, stat);
398
399     stat = GdipNewInstalledFontCollection(&collection);
400     expect (Ok, stat);
401     ok (collection != NULL, "got NULL font collection\n");
402 }
403
404 static void test_heightgivendpi(void)
405 {
406     GpStatus stat;
407     GpFont* font = NULL;
408     GpFontFamily* fontfamily = NULL;
409     REAL height;
410     Unit unit;
411
412     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
413     expect(Ok, stat);
414
415     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
416     expect(Ok, stat);
417
418     stat = GdipGetFontHeightGivenDPI(NULL, 96, &height);
419     expect(InvalidParameter, stat);
420
421     stat = GdipGetFontHeightGivenDPI(font, 96, NULL);
422     expect(InvalidParameter, stat);
423
424     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
425     expect(Ok, stat);
426     expectf(36.210938, height);
427     GdipDeleteFont(font);
428
429     height = 12345;
430     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font);
431     expect(Ok, stat);
432
433     stat = GdipGetFontUnit(font, &unit);
434     expect(Ok, stat);
435     expect(UnitWorld, unit);
436
437     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
438     expect(Ok, stat);
439     expectf(36.210938, height);
440     GdipDeleteFont(font);
441
442     height = 12345;
443     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font);
444     expect(Ok, stat);
445     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
446     expect(Ok, stat);
447     expectf(48.281250, height);
448     GdipDeleteFont(font);
449
450     height = 12345;
451     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font);
452     expect(Ok, stat);
453
454     stat = GdipGetFontUnit(font, &unit);
455     expect(Ok, stat);
456     expect(UnitInch, unit);
457
458     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
459     expect(Ok, stat);
460     expectf(3476.250000, height);
461     GdipDeleteFont(font);
462
463     height = 12345;
464     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font);
465     expect(Ok, stat);
466
467     stat = GdipGetFontUnit(font, &unit);
468     expect(Ok, stat);
469     expect(UnitDocument, unit);
470
471     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
472     expect(Ok, stat);
473     expectf(11.587500, height);
474     GdipDeleteFont(font);
475
476     height = 12345;
477     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font);
478     expect(Ok, stat);
479
480     stat = GdipGetFontUnit(font, &unit);
481     expect(Ok, stat);
482     expect(UnitMillimeter, unit);
483
484     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
485     expect(Ok, stat);
486     expectf(136.860245, height);
487     GdipDeleteFont(font);
488
489     GdipDeleteFontFamily(fontfamily);
490 }
491
492 static int CALLBACK font_enum_proc(const LOGFONTW *lfe, const TEXTMETRICW *ntme,
493                                    DWORD type, LPARAM lparam)
494 {
495     NEWTEXTMETRICW *ntm = (NEWTEXTMETRICW *)lparam;
496
497     if (type != TRUETYPE_FONTTYPE) return 1;
498
499     *ntm = *(NEWTEXTMETRICW *)ntme;
500     return 0;
501 }
502
503 struct font_metrics
504 {
505     UINT16 em_height, line_spacing, ascent, descent;
506     REAL font_height, font_size;
507     INT lfHeight;
508 };
509
510 static void gdi_get_font_metrics(LOGFONTW *lf, struct font_metrics *fm)
511 {
512     HDC hdc;
513     HFONT hfont;
514     NEWTEXTMETRICW ntm;
515     OUTLINETEXTMETRICW otm;
516     int ret;
517
518     hdc = CreateCompatibleDC(0);
519
520     /* it's the only way to get extended NEWTEXTMETRIC fields */
521     ret = EnumFontFamiliesExW(hdc, lf, font_enum_proc, (LPARAM)&ntm, 0);
522     ok(!ret, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf->lfFaceName));
523
524     hfont = CreateFontIndirectW(lf);
525     SelectObject(hdc, hfont);
526
527     otm.otmSize = sizeof(otm);
528     ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
529     ok(ret, "GetOutlineTextMetrics failed\n");
530
531     DeleteDC(hdc);
532     DeleteObject(hfont);
533
534     fm->lfHeight = -otm.otmTextMetrics.tmAscent;
535     fm->line_spacing = ntm.ntmCellHeight;
536     fm->font_size = (REAL)otm.otmTextMetrics.tmAscent;
537     fm->font_height = (REAL)fm->line_spacing * fm->font_size / (REAL)ntm.ntmSizeEM;
538     fm->em_height = ntm.ntmSizeEM;
539     fm->ascent = ntm.ntmSizeEM;
540     fm->descent = ntm.ntmCellHeight - ntm.ntmSizeEM;
541 }
542
543 static void gdip_get_font_metrics(GpFont *font, struct font_metrics *fm)
544 {
545     INT style;
546     GpFontFamily *family;
547     GpStatus stat;
548
549     stat = GdipGetFontStyle(font, &style);
550     expect(Ok, stat);
551
552     stat = GdipGetFontHeight(font, NULL, &fm->font_height);
553     expect(Ok, stat);
554     stat = GdipGetFontSize(font, &fm->font_size);
555     expect(Ok, stat);
556
557     fm->lfHeight = (INT)(fm->font_size * -1.0);
558
559     stat = GdipGetFamily(font, &family);
560     expect(Ok, stat);
561
562     stat = GdipGetEmHeight(family, style, &fm->em_height);
563     expect(Ok, stat);
564     stat = GdipGetLineSpacing(family, style, &fm->line_spacing);
565     expect(Ok, stat);
566     stat = GdipGetCellAscent(family, style, &fm->ascent);
567     expect(Ok, stat);
568     stat = GdipGetCellDescent(family, style, &fm->descent);
569     expect(Ok, stat);
570
571     GdipDeleteFontFamily(family);
572 }
573
574 static void cmp_font_metrics(struct font_metrics *fm1, struct font_metrics *fm2, int line)
575 {
576     ok_(__FILE__, line)(fm1->lfHeight == fm2->lfHeight, "lfHeight %d != %d\n", fm1->lfHeight, fm2->lfHeight);
577     ok_(__FILE__, line)(fm1->em_height == fm2->em_height, "em_height %u != %u\n", fm1->em_height, fm2->em_height);
578     ok_(__FILE__, line)(fm1->line_spacing == fm2->line_spacing, "line_spacing %u != %u\n", fm1->line_spacing, fm2->line_spacing);
579     ok_(__FILE__, line)(abs(fm1->ascent - fm2->ascent) <= 1, "ascent %u != %u\n", fm1->ascent, fm2->ascent);
580     ok_(__FILE__, line)(abs(fm1->descent - fm2->descent) <= 1, "descent %u != %u\n", fm1->descent, fm2->descent);
581     ok(fm1->font_height > 0.0, "fm1->font_height should be positive, got %f\n", fm1->font_height);
582     ok(fm2->font_height > 0.0, "fm2->font_height should be positive, got %f\n", fm2->font_height);
583     ok_(__FILE__, line)(fm1->font_height == fm2->font_height, "font_height %f != %f\n", fm1->font_height, fm2->font_height);
584     ok(fm1->font_size > 0.0, "fm1->font_size should be positive, got %f\n", fm1->font_size);
585     ok(fm2->font_size > 0.0, "fm2->font_size should be positive, got %f\n", fm2->font_size);
586     ok_(__FILE__, line)(fm1->font_size == fm2->font_size, "font_size %f != %f\n", fm1->font_size, fm2->font_size);
587 }
588
589 static void test_font_metrics(void)
590 {
591     LOGFONTW lf;
592     GpFont *font;
593     GpFontFamily *family;
594     GpGraphics *graphics;
595     GpStatus stat;
596     Unit unit;
597     struct font_metrics fm_gdi, fm_gdip;
598     HDC hdc;
599
600     hdc = CreateCompatibleDC(0);
601     stat = GdipCreateFromHDC(hdc, &graphics);
602     expect(Ok, stat);
603
604     memset(&lf, 0, sizeof(lf));
605
606     /* Tahoma,-13 */
607     lstrcpyW(lf.lfFaceName, Tahoma);
608     lf.lfHeight = -13;
609     stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
610     expect(Ok, stat);
611
612     stat = GdipGetFontUnit(font, &unit);
613     expect(Ok, stat);
614     expect(UnitWorld, unit);
615
616     gdip_get_font_metrics(font, &fm_gdip);
617     trace("gdiplus:\n");
618     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
619           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
620           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
621           fm_gdip.font_height, fm_gdip.font_size);
622
623     gdi_get_font_metrics(&lf, &fm_gdi);
624     trace("gdi:\n");
625     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
626           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
627           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
628           fm_gdi.font_height, fm_gdi.font_size);
629
630     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
631
632     stat = GdipGetLogFontW(font, graphics, &lf);
633     expect(Ok, stat);
634     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
635     gdi_get_font_metrics(&lf, &fm_gdi);
636     trace("gdi:\n");
637     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
638           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
639           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
640           fm_gdi.font_height, fm_gdi.font_size);
641     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
642
643     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
644
645     GdipDeleteFont(font);
646
647     /* Tahoma,13 */
648     lstrcpyW(lf.lfFaceName, Tahoma);
649     lf.lfHeight = 13;
650     stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
651     expect(Ok, stat);
652
653     stat = GdipGetFontUnit(font, &unit);
654     expect(Ok, stat);
655     expect(UnitWorld, unit);
656
657     gdip_get_font_metrics(font, &fm_gdip);
658     trace("gdiplus:\n");
659     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
660           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
661           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
662           fm_gdip.font_height, fm_gdip.font_size);
663
664     gdi_get_font_metrics(&lf, &fm_gdi);
665     trace("gdi:\n");
666     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
667           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
668           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
669           fm_gdi.font_height, fm_gdi.font_size);
670
671     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
672
673     stat = GdipGetLogFontW(font, graphics, &lf);
674     expect(Ok, stat);
675     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
676     gdi_get_font_metrics(&lf, &fm_gdi);
677     trace("gdi:\n");
678     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
679           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
680           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
681           fm_gdi.font_height, fm_gdi.font_size);
682     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
683
684     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
685
686     GdipDeleteFont(font);
687
688     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
689     expect(Ok, stat);
690
691     /* Tahoma,13 */
692     stat = GdipCreateFont(family, 13.0, FontStyleRegular, UnitPixel, &font);
693     expect(Ok, stat);
694
695     gdip_get_font_metrics(font, &fm_gdip);
696     trace("gdiplus:\n");
697     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
698           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
699           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
700           fm_gdip.font_height, fm_gdip.font_size);
701
702     stat = GdipGetLogFontW(font, graphics, &lf);
703     expect(Ok, stat);
704     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
705     gdi_get_font_metrics(&lf, &fm_gdi);
706     trace("gdi:\n");
707     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
708           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
709           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
710           fm_gdi.font_height, fm_gdi.font_size);
711     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
712
713     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
714
715     stat = GdipGetLogFontW(font, NULL, &lf);
716     expect(InvalidParameter, stat);
717
718     GdipDeleteFont(font);
719
720     stat = GdipCreateFont(family, -13.0, FontStyleRegular, UnitPixel, &font);
721     expect(InvalidParameter, stat);
722
723     GdipDeleteFontFamily(family);
724
725     GdipDeleteGraphics(graphics);
726     DeleteDC(hdc);
727 }
728
729 static void test_font_substitution(void)
730 {
731     WCHAR ms_shell_dlg[LF_FACESIZE];
732     HDC hdc;
733     HFONT hfont;
734     LOGFONT lf;
735     GpStatus status;
736     GpGraphics *graphics;
737     GpFont *font;
738     GpFontFamily *family;
739     int ret;
740
741     hdc = CreateCompatibleDC(0);
742     status = GdipCreateFromHDC(hdc, &graphics);
743     expect(Ok, status);
744
745     hfont = GetStockObject(DEFAULT_GUI_FONT);
746     ok(hfont != 0, "GetStockObject(DEFAULT_GUI_FONT) failed\n");
747
748     memset(&lf, 0xfe, sizeof(lf));
749     ret = GetObject(hfont, sizeof(lf), &lf);
750     ok(ret == sizeof(lf), "GetObject failed\n");
751     ok(!lstrcmp(lf.lfFaceName, "MS Shell Dlg"), "wrong face name %s\n", lf.lfFaceName);
752     MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, -1, ms_shell_dlg, LF_FACESIZE);
753
754     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
755     expect(Ok, status);
756     memset(&lf, 0xfe, sizeof(lf));
757     status = GdipGetLogFontA(font, graphics, &lf);
758     expect(Ok, status);
759     ok(!lstrcmp(lf.lfFaceName, "Microsoft Sans Serif") ||
760        !lstrcmp(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
761     GdipDeleteFont(font);
762
763     status = GdipCreateFontFamilyFromName(ms_shell_dlg, NULL, &family);
764     expect(Ok, status);
765     status = GdipCreateFont(family, 12, FontStyleRegular, UnitPoint, &font);
766     expect(Ok, status);
767     memset(&lf, 0xfe, sizeof(lf));
768     status = GdipGetLogFontA(font, graphics, &lf);
769     expect(Ok, status);
770     ok(!lstrcmp(lf.lfFaceName, "Microsoft Sans Serif") ||
771        !lstrcmp(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
772     GdipDeleteFont(font);
773     GdipDeleteFontFamily(family);
774
775     status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family);
776     ok(status == FontFamilyNotFound, "expected FontFamilyNotFound, got %d\n", status);
777
778     lstrcpy(lf.lfFaceName, "ThisFontShouldNotExist");
779     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
780     expect(Ok, status);
781     memset(&lf, 0xfe, sizeof(lf));
782     status = GdipGetLogFontA(font, graphics, &lf);
783     expect(Ok, status);
784     ok(!lstrcmp(lf.lfFaceName, "Arial"), "wrong face name %s\n", lf.lfFaceName);
785     GdipDeleteFont(font);
786
787     /* empty FaceName */
788     lf.lfFaceName[0] = 0;
789     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
790     expect(Ok, status);
791     memset(&lf, 0xfe, sizeof(lf));
792     status = GdipGetLogFontA(font, graphics, &lf);
793     expect(Ok, status);
794     ok(!lstrcmp(lf.lfFaceName, "Arial"), "wrong face name %s\n", lf.lfFaceName);
795     GdipDeleteFont(font);
796
797     /* zeroing out lfWeight and lfCharSet leads to font creation failure */
798     lf.lfWeight = 0;
799     lf.lfCharSet = 0;
800     lstrcpy(lf.lfFaceName, "ThisFontShouldNotExist");
801     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
802 todo_wine
803     ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
804        "expected NotTrueTypeFont, got %d\n", status);
805
806     /* empty FaceName */
807     lf.lfFaceName[0] = 0;
808     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
809 todo_wine
810     ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
811        "expected NotTrueTypeFont, got %d\n", status);
812
813     GdipDeleteGraphics(graphics);
814     DeleteDC(hdc);
815 }
816
817 static void test_font_transform(void)
818 {
819     static const WCHAR string[] = { 'A',0 };
820     GpStatus status;
821     HDC hdc;
822     LOGFONT lf;
823     GpFont *font;
824     GpGraphics *graphics;
825     GpMatrix *matrix;
826     GpStringFormat *format, *typographic;
827     PointF pos[1] = { { 0,0 } };
828     REAL height, margin_y;
829     RectF bounds, rect;
830
831     hdc = CreateCompatibleDC(0);
832     status = GdipCreateFromHDC(hdc, &graphics);
833     expect(Ok, status);
834
835     status = GdipSetPageUnit(graphics, UnitPixel);
836     expect(Ok, status);
837
838     status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
839     expect(Ok, status);
840     status = GdipStringFormatGetGenericTypographic(&typographic);
841     expect(Ok, status);
842
843     memset(&lf, 0, sizeof(lf));
844     lstrcpy(lf.lfFaceName, "Tahoma");
845     lf.lfHeight = -100;
846     lf.lfWidth = 100;
847     status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
848     expect(Ok, status);
849
850     margin_y = 100.0 / 8.0;
851
852     /* identity matrix */
853     status = GdipCreateMatrix(&matrix);
854     expect(Ok, status);
855     status = GdipSetWorldTransform(graphics, matrix);
856     expect(Ok, status);
857     status = GdipGetLogFontA(font, graphics, &lf);
858     expect(Ok, status);
859     expect(-100, lf.lfHeight);
860     expect(0, lf.lfWidth);
861     expect(0, lf.lfEscapement);
862     expect(0, lf.lfOrientation);
863     status = GdipGetFontHeight(font, graphics, &height);
864     expect(Ok, status);
865     expectf(120.703125, height);
866     set_rect_empty(&rect);
867     set_rect_empty(&bounds);
868     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
869     expect(Ok, status);
870     expectf(0.0, bounds.X);
871     expectf(0.0, bounds.Y);
872 todo_wine
873     expectf(height + margin_y, bounds.Height);
874     set_rect_empty(&rect);
875     set_rect_empty(&bounds);
876     status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
877     expect(Ok, status);
878     expectf(0.0, bounds.X);
879     expectf(0.0, bounds.Y);
880 todo_wine
881     expectf(height, bounds.Height);
882     set_rect_empty(&bounds);
883     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
884                                      DriverStringOptionsCmapLookup, NULL, &bounds);
885     expect(Ok, status);
886     expectf(0.0, bounds.X);
887 todo_wine
888     expectf_(-100.0, bounds.Y, 0.05);
889 todo_wine
890     expectf(height, bounds.Height);
891     set_rect_empty(&bounds);
892     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
893                                      DriverStringOptionsCmapLookup, matrix, &bounds);
894     expect(Ok, status);
895     expectf(0.0, bounds.X);
896 todo_wine
897     expectf_(-100.0, bounds.Y, 0.05);
898 todo_wine
899     expectf(height, bounds.Height);
900
901     /* scale matrix */
902     status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend);
903     expect(Ok, status);
904     status = GdipSetWorldTransform(graphics, matrix);
905     expect(Ok, status);
906     status = GdipGetLogFontA(font, graphics, &lf);
907     expect(Ok, status);
908     expect(-300, lf.lfHeight);
909     expect(0, lf.lfWidth);
910     expect(0, lf.lfEscapement);
911     expect(0, lf.lfOrientation);
912     status = GdipGetFontHeight(font, graphics, &height);
913     expect(Ok, status);
914     expectf(120.703125, height);
915     set_rect_empty(&rect);
916     set_rect_empty(&bounds);
917     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
918     expect(Ok, status);
919     expectf(0.0, bounds.X);
920     expectf(0.0, bounds.Y);
921 todo_wine
922     expectf(height + margin_y, bounds.Height);
923     set_rect_empty(&rect);
924     set_rect_empty(&bounds);
925     status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
926     expect(Ok, status);
927     expectf(0.0, bounds.X);
928     expectf(0.0, bounds.Y);
929 todo_wine
930     expectf(height, bounds.Height);
931     set_rect_empty(&bounds);
932     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
933                                      DriverStringOptionsCmapLookup, NULL, &bounds);
934     expect(Ok, status);
935     expectf(0.0, bounds.X);
936 todo_wine
937     expectf_(-100.0, bounds.Y, 0.05);
938 todo_wine
939     expectf(height, bounds.Height);
940     set_rect_empty(&bounds);
941     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
942                                      DriverStringOptionsCmapLookup, matrix, &bounds);
943     expect(Ok, status);
944     expectf(0.0, bounds.X);
945 todo_wine
946     expectf_(-300.0, bounds.Y, 0.15);
947 todo_wine
948     expectf(height * 3.0, bounds.Height);
949
950     /* scale + ratate matrix */
951     status = GdipRotateMatrix(matrix, 45.0, MatrixOrderAppend);
952     expect(Ok, status);
953     status = GdipSetWorldTransform(graphics, matrix);
954     expect(Ok, status);
955     status = GdipGetLogFontA(font, graphics, &lf);
956     expect(Ok, status);
957     expect(-300, lf.lfHeight);
958     expect(0, lf.lfWidth);
959     expect_(3151, lf.lfEscapement, 1);
960     expect_(3151, lf.lfOrientation, 1);
961     status = GdipGetFontHeight(font, graphics, &height);
962     expect(Ok, status);
963     expectf(120.703125, height);
964     set_rect_empty(&rect);
965     set_rect_empty(&bounds);
966     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
967     expect(Ok, status);
968     expectf(0.0, bounds.X);
969     expectf(0.0, bounds.Y);
970 todo_wine
971     expectf(height + margin_y, bounds.Height);
972     set_rect_empty(&rect);
973     set_rect_empty(&bounds);
974     status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
975     expect(Ok, status);
976     expectf(0.0, bounds.X);
977     expectf(0.0, bounds.Y);
978 todo_wine
979     expectf(height, bounds.Height);
980     set_rect_empty(&bounds);
981     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
982                                      DriverStringOptionsCmapLookup, NULL, &bounds);
983     expect(Ok, status);
984     expectf(0.0, bounds.X);
985 todo_wine
986     expectf_(-100.0, bounds.Y, 0.05);
987 todo_wine
988     expectf(height, bounds.Height);
989     set_rect_empty(&bounds);
990     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
991                                      DriverStringOptionsCmapLookup, matrix, &bounds);
992     expect(Ok, status);
993 todo_wine
994     expectf_(-43.814377, bounds.X, 0.05);
995 todo_wine
996     expectf_(-212.235611, bounds.Y, 0.05);
997 todo_wine
998     expectf_(340.847534, bounds.Height, 0.05);
999
1000     /* scale + ratate + shear matrix */
1001     status = GdipShearMatrix(matrix, 4.0, 5.0, MatrixOrderAppend);
1002     expect(Ok, status);
1003     status = GdipSetWorldTransform(graphics, matrix);
1004     expect(Ok, status);
1005     status = GdipGetLogFontA(font, graphics, &lf);
1006     expect(Ok, status);
1007 todo_wine
1008     expect(1032, lf.lfHeight);
1009     expect(0, lf.lfWidth);
1010     expect_(3099, lf.lfEscapement, 1);
1011     expect_(3099, lf.lfOrientation, 1);
1012     status = GdipGetFontHeight(font, graphics, &height);
1013     expect(Ok, status);
1014     expectf(120.703125, height);
1015     set_rect_empty(&rect);
1016     set_rect_empty(&bounds);
1017     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1018     expect(Ok, status);
1019     expectf(0.0, bounds.X);
1020     expectf(0.0, bounds.Y);
1021 todo_wine
1022     expectf(height + margin_y, bounds.Height);
1023     set_rect_empty(&rect);
1024     set_rect_empty(&bounds);
1025     status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1026     expect(Ok, status);
1027     expectf(0.0, bounds.X);
1028     expectf(0.0, bounds.Y);
1029 todo_wine
1030     expectf(height, bounds.Height);
1031     set_rect_empty(&bounds);
1032     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1033                                      DriverStringOptionsCmapLookup, NULL, &bounds);
1034     expect(Ok, status);
1035     expectf(0.0, bounds.X);
1036 todo_wine
1037     expectf_(-100.0, bounds.Y, 0.05);
1038 todo_wine
1039     expectf(height, bounds.Height);
1040     set_rect_empty(&bounds);
1041     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1042                                      DriverStringOptionsCmapLookup, matrix, &bounds);
1043     expect(Ok, status);
1044 todo_wine
1045     expectf_(-636.706848, bounds.X, 0.05);
1046 todo_wine
1047     expectf_(-175.257523, bounds.Y, 0.05);
1048 todo_wine
1049     expectf_(1532.984985, bounds.Height, 0.05);
1050
1051     /* scale + ratate + shear + translate matrix */
1052     status = GdipTranslateMatrix(matrix, 10.0, 20.0, MatrixOrderAppend);
1053     expect(Ok, status);
1054     status = GdipSetWorldTransform(graphics, matrix);
1055     expect(Ok, status);
1056     status = GdipGetLogFontA(font, graphics, &lf);
1057     expect(Ok, status);
1058 todo_wine
1059     expect(1032, lf.lfHeight);
1060     expect(0, lf.lfWidth);
1061     expect_(3099, lf.lfEscapement, 1);
1062     expect_(3099, lf.lfOrientation, 1);
1063     status = GdipGetFontHeight(font, graphics, &height);
1064     expect(Ok, status);
1065     expectf(120.703125, height);
1066     set_rect_empty(&rect);
1067     set_rect_empty(&bounds);
1068     status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1069     expect(Ok, status);
1070     expectf(0.0, bounds.X);
1071     expectf(0.0, bounds.Y);
1072 todo_wine
1073     expectf(height + margin_y, bounds.Height);
1074     set_rect_empty(&rect);
1075     set_rect_empty(&bounds);
1076     status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1077     expect(Ok, status);
1078     expectf(0.0, bounds.X);
1079     expectf(0.0, bounds.Y);
1080 todo_wine
1081     expectf(height, bounds.Height);
1082     set_rect_empty(&bounds);
1083     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1084                                      DriverStringOptionsCmapLookup, NULL, &bounds);
1085     expect(Ok, status);
1086     expectf(0.0, bounds.X);
1087 todo_wine
1088     expectf_(-100.0, bounds.Y, 0.05);
1089 todo_wine
1090     expectf(height, bounds.Height);
1091     set_rect_empty(&bounds);
1092     status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1093                                      DriverStringOptionsCmapLookup, matrix, &bounds);
1094     expect(Ok, status);
1095 todo_wine
1096     expectf_(-626.706848, bounds.X, 0.05);
1097 todo_wine
1098     expectf_(-155.257523, bounds.Y, 0.05);
1099 todo_wine
1100     expectf_(1532.984985, bounds.Height, 0.05);
1101
1102     GdipDeleteMatrix(matrix);
1103     GdipDeleteFont(font);
1104     GdipDeleteGraphics(graphics);
1105     GdipDeleteStringFormat(typographic);
1106     GdipDeleteStringFormat(format);
1107     DeleteDC(hdc);
1108 }
1109
1110 START_TEST(font)
1111 {
1112     struct GdiplusStartupInput gdiplusStartupInput;
1113     ULONG_PTR gdiplusToken;
1114
1115     gdiplusStartupInput.GdiplusVersion              = 1;
1116     gdiplusStartupInput.DebugEventCallback          = NULL;
1117     gdiplusStartupInput.SuppressBackgroundThread    = 0;
1118     gdiplusStartupInput.SuppressExternalCodecs      = 0;
1119
1120     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1121
1122     test_font_transform();
1123     test_font_substitution();
1124     test_font_metrics();
1125     test_createfont();
1126     test_logfont();
1127     test_fontfamily();
1128     test_fontfamily_properties();
1129     test_getgenerics();
1130     test_installedfonts();
1131     test_heightgivendpi();
1132
1133     GdiplusShutdown(gdiplusToken);
1134 }