winex11: Use the create_pixmap_from_image helper to select DIB pattern brushes.
[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 expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %f, got %f\n", expected, got)
30
31 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'};
32 static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
33 static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
34 static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
35 static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
36 static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
37 static const WCHAR LiberationSerif[] = {'L','i','b','e','r','a','t','i','o','n',' ','S','e','r','i','f',0};
38
39 static void test_createfont(void)
40 {
41     GpFontFamily* fontfamily = NULL, *fontfamily2;
42     GpFont* font = NULL;
43     GpStatus stat;
44     Unit unit;
45     UINT i;
46     REAL size;
47     WCHAR familyname[LF_FACESIZE];
48
49     stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily);
50     expect (FontFamilyNotFound, stat);
51     stat = GdipDeleteFont(font);
52     expect (InvalidParameter, stat);
53     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
54     expect (Ok, stat);
55     stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
56     expect (Ok, stat);
57     stat = GdipGetFontUnit (font, &unit);
58     expect (Ok, stat);
59     expect (UnitPoint, unit);
60
61     stat = GdipGetFamily(font, &fontfamily2);
62     expect(Ok, stat);
63     stat = GdipGetFamilyName(fontfamily2, familyname, 0);
64     expect(Ok, stat);
65     ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
66             wine_dbgstr_w(familyname));
67     stat = GdipDeleteFontFamily(fontfamily2);
68     expect(Ok, stat);
69
70     /* Test to see if returned size is based on unit (its not) */
71     GdipGetFontSize(font, &size);
72     ok (size == 12, "Expected 12, got %f\n", size);
73     GdipDeleteFont(font);
74
75     /* Make sure everything is converted correctly for all Units */
76     for (i = UnitWorld; i <=UnitMillimeter; i++)
77     {
78         if (i == UnitDisplay) continue; /* Crashes WindowsXP, wtf? */
79         GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font);
80         GdipGetFontSize (font, &size);
81         ok (size == 24, "Expected 24, got %f (with unit: %d)\n", size, i);
82         GdipGetFontUnit (font, &unit);
83         expect (i, unit);
84         GdipDeleteFont(font);
85     }
86
87     GdipDeleteFontFamily(fontfamily);
88 }
89
90 static void test_logfont(void)
91 {
92     LOGFONTA lfa, lfa2;
93     GpFont *font;
94     GpFontFamily *family;
95     GpStatus stat;
96     GpGraphics *graphics;
97     HDC hdc = GetDC(0);
98     INT style;
99     REAL rval;
100     UINT16 em_height, line_spacing;
101     Unit unit;
102
103     GdipCreateFromHDC(hdc, &graphics);
104
105     memset(&lfa, 0, sizeof(LOGFONTA));
106     memset(&lfa2, 0xff, sizeof(LOGFONTA));
107
108     /* empty FaceName */
109     lfa.lfFaceName[0] = 0;
110     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
111     expect(NotTrueTypeFont, stat);
112
113     lstrcpyA(lfa.lfFaceName, "Tahoma");
114
115     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
116     expect(Ok, stat);
117     stat = GdipGetLogFontA(font, graphics, &lfa2);
118     expect(Ok, stat);
119
120     ok(lfa2.lfHeight < 0, "Expected negative height\n");
121     expect(0, lfa2.lfWidth);
122     expect(0, lfa2.lfEscapement);
123     expect(0, lfa2.lfOrientation);
124     ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
125     expect(0, lfa2.lfItalic);
126     expect(0, lfa2.lfUnderline);
127     expect(0, lfa2.lfStrikeOut);
128     ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
129         "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
130     expect(0, lfa2.lfOutPrecision);
131     expect(0, lfa2.lfClipPrecision);
132     expect(0, lfa2.lfQuality);
133     expect(0, lfa2.lfPitchAndFamily);
134
135     GdipDeleteFont(font);
136
137     memset(&lfa, 0, sizeof(LOGFONTA));
138     lfa.lfHeight = 25;
139     lfa.lfWidth = 25;
140     lfa.lfEscapement = lfa.lfOrientation = 50;
141     lfa.lfItalic = lfa.lfUnderline = lfa.lfStrikeOut = TRUE;
142
143     memset(&lfa2, 0xff, sizeof(LOGFONTA));
144     lstrcpyA(lfa.lfFaceName, "Tahoma");
145
146     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
147     expect(Ok, stat);
148     stat = GdipGetLogFontA(font, graphics, &lfa2);
149     expect(Ok, stat);
150
151     ok(lfa2.lfHeight < 0, "Expected negative height\n");
152     expect(0, lfa2.lfWidth);
153     expect(0, lfa2.lfEscapement);
154     expect(0, lfa2.lfOrientation);
155     ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
156     expect(TRUE, lfa2.lfItalic);
157     expect(TRUE, lfa2.lfUnderline);
158     expect(TRUE, lfa2.lfStrikeOut);
159     ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
160         "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
161     expect(0, lfa2.lfOutPrecision);
162     expect(0, lfa2.lfClipPrecision);
163     expect(0, lfa2.lfQuality);
164     expect(0, lfa2.lfPitchAndFamily);
165
166     stat = GdipGetFontStyle(font, &style);
167     expect(Ok, stat);
168     ok (style == (FontStyleItalic | FontStyleUnderline | FontStyleStrikeout),
169             "Expected , got %d\n", style);
170
171     stat = GdipGetFontUnit(font, &unit);
172     expect(Ok, stat);
173     expect(UnitWorld, unit);
174
175     stat = GdipGetFontHeight(font, graphics, &rval);
176     expect(Ok, stat);
177     expectf(25.347656, rval);
178     stat = GdipGetFontSize(font, &rval);
179     expect(Ok, stat);
180     expectf(21.0, rval);
181
182     stat = GdipGetFamily(font, &family);
183     expect(Ok, stat);
184     stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
185     expect(Ok, stat);
186     expect(2048, em_height);
187     stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
188     expect(Ok, stat);
189     expect(2472, line_spacing);
190     GdipDeleteFontFamily(family);
191
192     GdipDeleteFont(font);
193
194     memset(&lfa, 0, sizeof(lfa));
195     lfa.lfHeight = -25;
196     lstrcpyA(lfa.lfFaceName, "Tahoma");
197     stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
198     expect(Ok, stat);
199     memset(&lfa2, 0xff, sizeof(lfa2));
200     stat = GdipGetLogFontA(font, graphics, &lfa2);
201     expect(Ok, stat);
202     expect(lfa.lfHeight, lfa2.lfHeight);
203
204     stat = GdipGetFontUnit(font, &unit);
205     expect(Ok, stat);
206     expect(UnitWorld, unit);
207
208     stat = GdipGetFontHeight(font, graphics, &rval);
209     expect(Ok, stat);
210     expectf(30.175781, rval);
211     stat = GdipGetFontSize(font, &rval);
212     expect(Ok, stat);
213     expectf(25.0, rval);
214
215     stat = GdipGetFamily(font, &family);
216     expect(Ok, stat);
217     stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
218     expect(Ok, stat);
219     expect(2048, em_height);
220     stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
221     expect(Ok, stat);
222     expect(2472, line_spacing);
223     GdipDeleteFontFamily(family);
224
225     GdipDeleteFont(font);
226
227     GdipDeleteGraphics(graphics);
228     ReleaseDC(0, hdc);
229 }
230
231 static void test_fontfamily (void)
232 {
233     GpFontFamily *family, *clonedFontFamily;
234     WCHAR itsName[LF_FACESIZE];
235     GpStatus stat;
236
237     /* FontFamily cannot be NULL */
238     stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
239     expect (InvalidParameter, stat);
240
241     /* FontFamily must be able to actually find the family.
242      * If it can't, any subsequent calls should fail.
243      */
244     stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
245     expect (FontFamilyNotFound, stat);
246
247     /* Bitmap fonts are not found */
248     stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
249     expect (FontFamilyNotFound, stat);
250     if(stat == Ok) GdipDeleteFontFamily(family);
251
252     stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
253     expect (Ok, stat);
254
255     stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
256     expect (Ok, stat);
257     expect (0, lstrcmpiW(itsName, Tahoma));
258
259     if (0)
260     {
261         /* Crashes on Windows XP SP2, Vista, and so Wine as well */
262         stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL);
263         expect (Ok, stat);
264     }
265
266     /* Make sure we don't read old data */
267     ZeroMemory (itsName, sizeof(itsName));
268     stat = GdipCloneFontFamily(family, &clonedFontFamily);
269     expect (Ok, stat);
270     GdipDeleteFontFamily(family);
271     stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
272     expect(Ok, stat);
273     expect(0, lstrcmpiW(itsName, Tahoma));
274
275     GdipDeleteFontFamily(clonedFontFamily);
276 }
277
278 static void test_fontfamily_properties (void)
279 {
280     GpFontFamily* FontFamily = NULL;
281     GpStatus stat;
282     UINT16 result = 0;
283
284     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
285     expect(Ok, stat);
286
287     stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
288     expect(Ok, stat);
289     ok (result == 2472, "Expected 2472, got %d\n", result);
290     result = 0;
291     stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
292     expect(Ok, stat);
293     ok(result == 2048, "Expected 2048, got %d\n", result);
294     result = 0;
295     stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
296     expect(Ok, stat);
297     ok(result == 2049, "Expected 2049, got %d\n", result);
298     result = 0;
299     stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
300     expect(Ok, stat);
301     ok(result == 423, "Expected 423, got %d\n", result);
302     GdipDeleteFontFamily(FontFamily);
303
304     stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
305     if(stat == FontFamilyNotFound)
306         skip("Times New Roman not installed\n");
307     else
308     {
309         result = 0;
310         stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
311         expect(Ok, stat);
312         ok(result == 2355, "Expected 2355, got %d\n", result);
313         result = 0;
314         stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
315         expect(Ok, stat);
316         ok(result == 2048, "Expected 2048, got %d\n", result);
317         result = 0;
318         stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
319         expect(Ok, stat);
320         ok(result == 1825, "Expected 1825, got %d\n", result);
321         result = 0;
322         stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
323         expect(Ok, stat);
324         ok(result == 443, "Expected 443 got %d\n", result);
325         GdipDeleteFontFamily(FontFamily);
326     }
327 }
328
329 static void check_family(const char* context, GpFontFamily *family, WCHAR *name)
330 {
331     GpStatus stat;
332     GpFont* font;
333
334     *name = 0;
335     stat = GdipGetFamilyName(family, name, LANG_NEUTRAL);
336     ok(stat == Ok, "could not get the %s family name: %.8x\n", context, stat);
337
338     stat = GdipCreateFont(family, 12, FontStyleRegular, UnitPixel, &font);
339     ok(stat == Ok, "could not create a font for the %s family: %.8x\n", context, stat);
340     if (stat == Ok)
341     {
342         stat = GdipDeleteFont(font);
343         ok(stat == Ok, "could not delete the %s family font: %.8x\n", context, stat);
344     }
345
346     stat = GdipDeleteFontFamily(family);
347     ok(stat == Ok, "could not delete the %s family: %.8x\n", context, stat);
348 }
349
350 static void test_getgenerics (void)
351 {
352     GpStatus stat;
353     GpFontFamily *family;
354     WCHAR sansname[LF_FACESIZE], serifname[LF_FACESIZE], mononame[LF_FACESIZE];
355     int missingfonts = 0;
356
357     stat = GdipGetGenericFontFamilySansSerif(&family);
358     expect (Ok, stat);
359     if (stat == FontFamilyNotFound)
360         missingfonts = 1;
361     else
362         check_family("Sans Serif", family, sansname);
363
364     stat = GdipGetGenericFontFamilySerif(&family);
365     expect (Ok, stat);
366     if (stat == FontFamilyNotFound)
367         missingfonts = 1;
368     else
369         check_family("Serif", family, serifname);
370
371     stat = GdipGetGenericFontFamilyMonospace(&family);
372     expect (Ok, stat);
373     if (stat == FontFamilyNotFound)
374         missingfonts = 1;
375     else
376         check_family("Monospace", family, mononame);
377
378     if (missingfonts && strcmp(winetest_platform, "wine") == 0)
379         trace("You may need to install either the Microsoft Web Fonts or the Liberation Fonts\n");
380
381     /* Check that the family names are all different */
382     ok(lstrcmpiW(sansname, serifname) != 0, "Sans Serif and Serif families should be different: %s\n", wine_dbgstr_w(sansname));
383     ok(lstrcmpiW(sansname, mononame) != 0, "Sans Serif and Monospace families should be different: %s\n", wine_dbgstr_w(sansname));
384     ok(lstrcmpiW(serifname, mononame) != 0, "Serif and Monospace families should be different: %s\n", wine_dbgstr_w(serifname));
385 }
386
387 static void test_installedfonts (void)
388 {
389     GpStatus stat;
390     GpFontCollection* collection=NULL;
391
392     stat = GdipNewInstalledFontCollection(NULL);
393     expect (InvalidParameter, stat);
394
395     stat = GdipNewInstalledFontCollection(&collection);
396     expect (Ok, stat);
397     ok (collection != NULL, "got NULL font collection\n");
398 }
399
400 static void test_heightgivendpi(void)
401 {
402     GpStatus stat;
403     GpFont* font = NULL;
404     GpFontFamily* fontfamily = NULL;
405     REAL height;
406     Unit unit;
407
408     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
409     expect(Ok, stat);
410
411     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
412     expect(Ok, stat);
413
414     stat = GdipGetFontHeightGivenDPI(NULL, 96, &height);
415     expect(InvalidParameter, stat);
416
417     stat = GdipGetFontHeightGivenDPI(font, 96, NULL);
418     expect(InvalidParameter, stat);
419
420     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
421     expect(Ok, stat);
422     expectf(36.210938, height);
423     GdipDeleteFont(font);
424
425     height = 12345;
426     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font);
427     expect(Ok, stat);
428
429     stat = GdipGetFontUnit(font, &unit);
430     expect(Ok, stat);
431     expect(UnitWorld, unit);
432
433     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
434     expect(Ok, stat);
435     expectf(36.210938, height);
436     GdipDeleteFont(font);
437
438     height = 12345;
439     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font);
440     expect(Ok, stat);
441     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
442     expect(Ok, stat);
443     expectf(48.281250, height);
444     GdipDeleteFont(font);
445
446     height = 12345;
447     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font);
448     expect(Ok, stat);
449
450     stat = GdipGetFontUnit(font, &unit);
451     expect(Ok, stat);
452     expect(UnitInch, unit);
453
454     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
455     expect(Ok, stat);
456     expectf(3476.250000, height);
457     GdipDeleteFont(font);
458
459     height = 12345;
460     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font);
461     expect(Ok, stat);
462
463     stat = GdipGetFontUnit(font, &unit);
464     expect(Ok, stat);
465     expect(UnitDocument, unit);
466
467     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
468     expect(Ok, stat);
469     expectf(11.587500, height);
470     GdipDeleteFont(font);
471
472     height = 12345;
473     stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font);
474     expect(Ok, stat);
475
476     stat = GdipGetFontUnit(font, &unit);
477     expect(Ok, stat);
478     expect(UnitMillimeter, unit);
479
480     stat = GdipGetFontHeightGivenDPI(font, 96, &height);
481     expect(Ok, stat);
482     expectf(136.860245, height);
483     GdipDeleteFont(font);
484
485     GdipDeleteFontFamily(fontfamily);
486 }
487
488 static int CALLBACK font_enum_proc(const LOGFONTW *lfe, const TEXTMETRICW *ntme,
489                                    DWORD type, LPARAM lparam)
490 {
491     NEWTEXTMETRICW *ntm = (NEWTEXTMETRICW *)lparam;
492
493     if (type != TRUETYPE_FONTTYPE) return 1;
494
495     *ntm = *(NEWTEXTMETRICW *)ntme;
496     return 0;
497 }
498
499 struct font_metrics
500 {
501     UINT16 em_height, line_spacing, ascent, descent;
502     REAL font_height, font_size;
503     INT lfHeight;
504 };
505
506 static void gdi_get_font_metrics(LOGFONTW *lf, struct font_metrics *fm)
507 {
508     HDC hdc;
509     HFONT hfont;
510     NEWTEXTMETRICW ntm;
511     OUTLINETEXTMETRICW otm;
512     int ret;
513
514     hdc = CreateCompatibleDC(0);
515
516     /* it's the only way to get extended NEWTEXTMETRIC fields */
517     ret = EnumFontFamiliesExW(hdc, lf, font_enum_proc, (LPARAM)&ntm, 0);
518     ok(!ret, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf->lfFaceName));
519
520     hfont = CreateFontIndirectW(lf);
521     SelectObject(hdc, hfont);
522
523     otm.otmSize = sizeof(otm);
524     ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
525     ok(ret, "GetOutlineTextMetrics failed\n");
526
527     DeleteDC(hdc);
528     DeleteObject(hfont);
529
530     fm->lfHeight = -otm.otmTextMetrics.tmAscent;
531     fm->line_spacing = ntm.ntmCellHeight;
532     fm->font_size = (REAL)otm.otmTextMetrics.tmAscent;
533     fm->font_height = (REAL)fm->line_spacing * fm->font_size / (REAL)ntm.ntmSizeEM;
534     fm->em_height = ntm.ntmSizeEM;
535     fm->ascent = ntm.ntmSizeEM;
536     fm->descent = ntm.ntmCellHeight - ntm.ntmSizeEM;
537 }
538
539 static void gdip_get_font_metrics(GpFont *font, struct font_metrics *fm)
540 {
541     INT style;
542     GpFontFamily *family;
543     GpStatus stat;
544
545     stat = GdipGetFontStyle(font, &style);
546     expect(Ok, stat);
547
548     stat = GdipGetFontHeight(font, NULL, &fm->font_height);
549     expect(Ok, stat);
550     stat = GdipGetFontSize(font, &fm->font_size);
551     expect(Ok, stat);
552
553     fm->lfHeight = (INT)(fm->font_size * -1.0);
554
555     stat = GdipGetFamily(font, &family);
556     expect(Ok, stat);
557
558     stat = GdipGetEmHeight(family, style, &fm->em_height);
559     expect(Ok, stat);
560     stat = GdipGetLineSpacing(family, style, &fm->line_spacing);
561     expect(Ok, stat);
562     stat = GdipGetCellAscent(family, style, &fm->ascent);
563     expect(Ok, stat);
564     stat = GdipGetCellDescent(family, style, &fm->descent);
565     expect(Ok, stat);
566
567     GdipDeleteFontFamily(family);
568 }
569
570 static void cmp_font_metrics(struct font_metrics *fm1, struct font_metrics *fm2, int line)
571 {
572     ok_(__FILE__, line)(fm1->lfHeight == fm2->lfHeight, "lfHeight %d != %d\n", fm1->lfHeight, fm2->lfHeight);
573     ok_(__FILE__, line)(fm1->em_height == fm2->em_height, "em_height %u != %u\n", fm1->em_height, fm2->em_height);
574     ok_(__FILE__, line)(fm1->line_spacing == fm2->line_spacing, "line_spacing %u != %u\n", fm1->line_spacing, fm2->line_spacing);
575     ok_(__FILE__, line)(abs(fm1->ascent - fm2->ascent) <= 1, "ascent %u != %u\n", fm1->ascent, fm2->ascent);
576     ok_(__FILE__, line)(abs(fm1->descent - fm2->descent) <= 1, "descent %u != %u\n", fm1->descent, fm2->descent);
577     ok(fm1->font_height > 0.0, "fm1->font_height should be positive, got %f\n", fm1->font_height);
578     ok(fm2->font_height > 0.0, "fm2->font_height should be positive, got %f\n", fm2->font_height);
579     ok_(__FILE__, line)(fm1->font_height == fm2->font_height, "font_height %f != %f\n", fm1->font_height, fm2->font_height);
580     ok(fm1->font_size > 0.0, "fm1->font_size should be positive, got %f\n", fm1->font_size);
581     ok(fm2->font_size > 0.0, "fm2->font_size should be positive, got %f\n", fm2->font_size);
582     ok_(__FILE__, line)(fm1->font_size == fm2->font_size, "font_size %f != %f\n", fm1->font_size, fm2->font_size);
583 }
584
585 static void test_font_metrics(void)
586 {
587     LOGFONTW lf;
588     GpFont *font;
589     GpFontFamily *family;
590     GpGraphics *graphics;
591     GpStatus stat;
592     Unit unit;
593     struct font_metrics fm_gdi, fm_gdip;
594     HDC hdc;
595
596     hdc = CreateCompatibleDC(0);
597     stat = GdipCreateFromHDC(hdc, &graphics);
598     expect(Ok, stat);
599
600     memset(&lf, 0, sizeof(lf));
601
602     /* Tahoma,-13 */
603     lstrcpyW(lf.lfFaceName, Tahoma);
604     lf.lfHeight = -13;
605     stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
606     expect(Ok, stat);
607
608     stat = GdipGetFontUnit(font, &unit);
609     expect(Ok, stat);
610     expect(UnitWorld, unit);
611
612     gdip_get_font_metrics(font, &fm_gdip);
613     trace("gdiplus:\n");
614     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
615           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
616           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
617           fm_gdip.font_height, fm_gdip.font_size);
618
619     gdi_get_font_metrics(&lf, &fm_gdi);
620     trace("gdi:\n");
621     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
622           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
623           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
624           fm_gdi.font_height, fm_gdi.font_size);
625
626     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
627
628     stat = GdipGetLogFontW(font, graphics, &lf);
629     expect(Ok, stat);
630     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
631     gdi_get_font_metrics(&lf, &fm_gdi);
632     trace("gdi:\n");
633     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
634           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
635           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
636           fm_gdi.font_height, fm_gdi.font_size);
637     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
638
639     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
640
641     GdipDeleteFont(font);
642
643     /* Tahoma,13 */
644     lstrcpyW(lf.lfFaceName, Tahoma);
645     lf.lfHeight = 13;
646     stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
647     expect(Ok, stat);
648
649     stat = GdipGetFontUnit(font, &unit);
650     expect(Ok, stat);
651     expect(UnitWorld, unit);
652
653     gdip_get_font_metrics(font, &fm_gdip);
654     trace("gdiplus:\n");
655     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
656           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
657           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
658           fm_gdip.font_height, fm_gdip.font_size);
659
660     gdi_get_font_metrics(&lf, &fm_gdi);
661     trace("gdi:\n");
662     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
663           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
664           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
665           fm_gdi.font_height, fm_gdi.font_size);
666
667     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
668
669     stat = GdipGetLogFontW(font, graphics, &lf);
670     expect(Ok, stat);
671     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
672     gdi_get_font_metrics(&lf, &fm_gdi);
673     trace("gdi:\n");
674     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
675           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
676           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
677           fm_gdi.font_height, fm_gdi.font_size);
678     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
679
680     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
681
682     GdipDeleteFont(font);
683
684     stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
685     expect(Ok, stat);
686
687     /* Tahoma,13 */
688     stat = GdipCreateFont(family, 13.0, FontStyleRegular, UnitPixel, &font);
689     expect(Ok, stat);
690
691     gdip_get_font_metrics(font, &fm_gdip);
692     trace("gdiplus:\n");
693     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
694           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
695           fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
696           fm_gdip.font_height, fm_gdip.font_size);
697
698     stat = GdipGetLogFontW(font, graphics, &lf);
699     expect(Ok, stat);
700     ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
701     gdi_get_font_metrics(&lf, &fm_gdi);
702     trace("gdi:\n");
703     trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
704           wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
705           fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
706           fm_gdi.font_height, fm_gdi.font_size);
707     ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
708
709     cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
710
711     stat = GdipGetLogFontW(font, NULL, &lf);
712     expect(InvalidParameter, stat);
713
714     GdipDeleteFont(font);
715
716     stat = GdipCreateFont(family, -13.0, FontStyleRegular, UnitPixel, &font);
717     expect(InvalidParameter, stat);
718
719     GdipDeleteFontFamily(family);
720
721     GdipDeleteGraphics(graphics);
722     DeleteDC(hdc);
723 }
724
725 START_TEST(font)
726 {
727     struct GdiplusStartupInput gdiplusStartupInput;
728     ULONG_PTR gdiplusToken;
729
730     gdiplusStartupInput.GdiplusVersion              = 1;
731     gdiplusStartupInput.DebugEventCallback          = NULL;
732     gdiplusStartupInput.SuppressBackgroundThread    = 0;
733     gdiplusStartupInput.SuppressExternalCodecs      = 0;
734
735     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
736
737     test_font_metrics();
738     test_createfont();
739     test_logfont();
740     test_fontfamily();
741     test_fontfamily_properties();
742     test_getgenerics();
743     test_installedfonts();
744     test_heightgivendpi();
745
746     GdiplusShutdown(gdiplusToken);
747 }