2 * Unit test suite for fonts
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012 Dmitry Timoshkov
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.
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.
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
26 #include "wine/test.h"
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)
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 TimesNewRoman
[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
36 static const WCHAR Tahoma
[] = {'T','a','h','o','m','a',0};
38 static void set_rect_empty(RectF
*rc
)
46 static void create_testfontfile(const WCHAR
*filename
, int resource
, WCHAR pathW
[MAX_PATH
])
53 GetTempPathW(MAX_PATH
, pathW
);
54 lstrcatW(pathW
, filename
);
56 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
57 ok(file
!= INVALID_HANDLE_VALUE
, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW
), GetLastError());
59 res
= FindResourceA(GetModuleHandleA(NULL
), MAKEINTRESOURCEA(resource
), (LPCSTR
)RT_RCDATA
);
60 ok(res
!= 0, "couldn't find resource\n");
61 ptr
= LockResource(LoadResource(GetModuleHandleA(NULL
), res
));
62 WriteFile(file
, ptr
, SizeofResource(GetModuleHandleA(NULL
), res
), &written
, NULL
);
63 ok(written
== SizeofResource(GetModuleHandleA(NULL
), res
), "couldn't write resource\n");
67 #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
68 static void _delete_testfontfile(const WCHAR
*filename
, int line
)
70 BOOL ret
= DeleteFileW(filename
);
71 ok_(__FILE__
,line
)(ret
, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename
), GetLastError());
74 static void test_long_name(void)
77 static const WCHAR path_longname
[] = {'w','i','n','e','_','l','o','n','g','n','a','m','e','.','t','t','f',0};
79 GpFontCollection
*fonts
;
82 WCHAR family_name
[LF_FACESIZE
];
85 stat
= GdipNewPrivateFontCollection(&fonts
);
86 ok(stat
== Ok
, "GdipNewPrivateFontCollection failed: %d\n", stat
);
88 create_testfontfile(path_longname
, 1, path
);
90 stat
= GdipPrivateAddFontFile(fonts
, path
);
91 ok(stat
== Ok
, "GdipPrivateAddFontFile failed: %d\n", stat
);
93 stat
= GdipGetFontCollectionFamilyCount(fonts
, &num_families
);
94 ok(stat
== Ok
, "GdipGetFontCollectionFamilyCount failed: %d\n", stat
);
96 ok(num_families
== 1, "expected num_families to be 1, got %d\n", num_families
);
98 stat
= GdipGetFontCollectionFamilyList(fonts
, num_families
, &family
, &num_families
);
99 ok(stat
== Ok
, "GdipGetFontCollectionFamilyList failed: %d\n", stat
);
101 stat
= GdipGetFamilyName(family
, family_name
, LANG_NEUTRAL
);
102 ok(stat
== Ok
, "GdipGetFamilyName failed: %d\n", stat
);
104 stat
= GdipCreateFont(family
, 256.0, FontStyleRegular
, UnitPixel
, &font
);
105 ok(stat
== Ok
, "GdipCreateFont failed: %d\n", stat
);
109 stat
= GdipDeleteFont(font
);
110 ok(stat
== Ok
, "GdipDeleteFont failed: %d\n", stat
);
112 stat
= GdipDeletePrivateFontCollection(&fonts
);
113 ok(stat
== Ok
, "GdipDeletePrivateFontCollection failed: %d\n", stat
);
115 DELETE_FONTFILE(path
);
118 static void test_createfont(void)
120 GpFontFamily
* fontfamily
= NULL
, *fontfamily2
;
126 WCHAR familyname
[LF_FACESIZE
];
128 stat
= GdipCreateFontFamilyFromName(nonexistent
, NULL
, &fontfamily
);
129 expect (FontFamilyNotFound
, stat
);
130 stat
= GdipDeleteFont(font
);
131 expect (InvalidParameter
, stat
);
132 stat
= GdipCreateFontFamilyFromName(Tahoma
, NULL
, &fontfamily
);
134 stat
= GdipCreateFont(fontfamily
, 12, FontStyleRegular
, UnitPoint
, &font
);
136 stat
= GdipGetFontUnit (font
, &unit
);
138 expect (UnitPoint
, unit
);
140 stat
= GdipGetFamily(font
, &fontfamily2
);
142 stat
= GdipGetFamilyName(fontfamily2
, familyname
, 0);
144 ok (lstrcmpiW(Tahoma
, familyname
) == 0, "Expected Tahoma, got %s\n",
145 wine_dbgstr_w(familyname
));
146 stat
= GdipDeleteFontFamily(fontfamily2
);
149 /* Test to see if returned size is based on unit (it's not) */
150 GdipGetFontSize(font
, &size
);
151 ok (size
== 12, "Expected 12, got %f\n", size
);
152 GdipDeleteFont(font
);
154 /* Make sure everything is converted correctly for all Units */
155 for (i
= UnitWorld
; i
<=UnitMillimeter
; i
++)
157 if (i
== UnitDisplay
) continue; /* Crashes WindowsXP, wtf? */
158 stat
= GdipCreateFont(fontfamily
, 24, FontStyleRegular
, i
, &font
);
160 GdipGetFontSize (font
, &size
);
161 ok (size
== 24, "Expected 24, got %f (with unit: %d)\n", size
, i
);
162 stat
= GdipGetFontUnit (font
, &unit
);
163 ok (stat
== Ok
, "Failed to get font unit, %d.\n", stat
);
165 GdipDeleteFont(font
);
168 GdipDeleteFontFamily(fontfamily
);
171 static void test_logfont(void)
175 GpFontFamily
*family
;
177 GpGraphics
*graphics
;
181 UINT16 em_height
, line_spacing
;
184 stat
= GdipCreateFromHDC(hdc
, &graphics
);
187 memset(&lfa
, 0, sizeof(LOGFONTA
));
188 memset(&lfa2
, 0xff, sizeof(LOGFONTA
));
189 lstrcpyA(lfa
.lfFaceName
, "Tahoma");
191 stat
= GdipCreateFontFromLogfontA(hdc
, &lfa
, &font
);
193 stat
= GdipGetLogFontA(font
, graphics
, &lfa2
);
196 ok(lfa2
.lfHeight
< 0, "Expected negative height\n");
197 expect(0, lfa2
.lfWidth
);
198 expect(0, lfa2
.lfEscapement
);
199 expect(0, lfa2
.lfOrientation
);
200 ok((lfa2
.lfWeight
>= 100) && (lfa2
.lfWeight
<= 900), "Expected weight to be set\n");
201 expect(0, lfa2
.lfItalic
);
202 expect(0, lfa2
.lfUnderline
);
203 expect(0, lfa2
.lfStrikeOut
);
204 ok(lfa2
.lfCharSet
== GetTextCharset(hdc
) || lfa2
.lfCharSet
== ANSI_CHARSET
,
205 "Expected %x or %x, got %x\n", GetTextCharset(hdc
), ANSI_CHARSET
, lfa2
.lfCharSet
);
206 expect(0, lfa2
.lfOutPrecision
);
207 expect(0, lfa2
.lfClipPrecision
);
208 expect(0, lfa2
.lfQuality
);
209 expect(0, lfa2
.lfPitchAndFamily
);
211 GdipDeleteFont(font
);
213 memset(&lfa
, 0, sizeof(LOGFONTA
));
216 lfa
.lfEscapement
= lfa
.lfOrientation
= 50;
217 lfa
.lfItalic
= lfa
.lfUnderline
= lfa
.lfStrikeOut
= TRUE
;
219 memset(&lfa2
, 0xff, sizeof(LOGFONTA
));
220 lstrcpyA(lfa
.lfFaceName
, "Tahoma");
222 stat
= GdipCreateFontFromLogfontA(hdc
, &lfa
, &font
);
224 stat
= GdipGetLogFontA(font
, graphics
, &lfa2
);
227 ok(lfa2
.lfHeight
< 0, "Expected negative height\n");
228 expect(0, lfa2
.lfWidth
);
229 expect(0, lfa2
.lfEscapement
);
230 expect(0, lfa2
.lfOrientation
);
231 ok((lfa2
.lfWeight
>= 100) && (lfa2
.lfWeight
<= 900), "Expected weight to be set\n");
232 expect(TRUE
, lfa2
.lfItalic
);
233 expect(TRUE
, lfa2
.lfUnderline
);
234 expect(TRUE
, lfa2
.lfStrikeOut
);
235 ok(lfa2
.lfCharSet
== GetTextCharset(hdc
) || lfa2
.lfCharSet
== ANSI_CHARSET
,
236 "Expected %x or %x, got %x\n", GetTextCharset(hdc
), ANSI_CHARSET
, lfa2
.lfCharSet
);
237 expect(0, lfa2
.lfOutPrecision
);
238 expect(0, lfa2
.lfClipPrecision
);
239 expect(0, lfa2
.lfQuality
);
240 expect(0, lfa2
.lfPitchAndFamily
);
242 stat
= GdipGetFontStyle(font
, &style
);
244 ok (style
== (FontStyleItalic
| FontStyleUnderline
| FontStyleStrikeout
),
245 "Expected , got %d\n", style
);
247 stat
= GdipGetFontUnit(font
, &unit
);
249 expect(UnitWorld
, unit
);
251 stat
= GdipGetFontHeight(font
, graphics
, &rval
);
253 expectf(25.347656, rval
);
254 stat
= GdipGetFontSize(font
, &rval
);
258 stat
= GdipGetFamily(font
, &family
);
260 stat
= GdipGetEmHeight(family
, FontStyleRegular
, &em_height
);
262 expect(2048, em_height
);
263 stat
= GdipGetLineSpacing(family
, FontStyleRegular
, &line_spacing
);
265 expect(2472, line_spacing
);
266 GdipDeleteFontFamily(family
);
268 GdipDeleteFont(font
);
270 memset(&lfa
, 0, sizeof(lfa
));
272 lstrcpyA(lfa
.lfFaceName
, "Tahoma");
273 stat
= GdipCreateFontFromLogfontA(hdc
, &lfa
, &font
);
275 memset(&lfa2
, 0xff, sizeof(lfa2
));
276 stat
= GdipGetLogFontA(font
, graphics
, &lfa2
);
278 expect(lfa
.lfHeight
, lfa2
.lfHeight
);
280 stat
= GdipGetFontUnit(font
, &unit
);
282 expect(UnitWorld
, unit
);
284 stat
= GdipGetFontHeight(font
, graphics
, &rval
);
286 expectf(30.175781, rval
);
287 stat
= GdipGetFontSize(font
, &rval
);
291 stat
= GdipGetFamily(font
, &family
);
293 stat
= GdipGetEmHeight(family
, FontStyleRegular
, &em_height
);
295 expect(2048, em_height
);
296 stat
= GdipGetLineSpacing(family
, FontStyleRegular
, &line_spacing
);
298 expect(2472, line_spacing
);
299 GdipDeleteFontFamily(family
);
301 GdipDeleteFont(font
);
303 GdipDeleteGraphics(graphics
);
307 static void test_fontfamily (void)
309 GpFontFamily
*family
, *clonedFontFamily
;
310 WCHAR itsName
[LF_FACESIZE
];
313 /* FontFamily cannot be NULL */
314 stat
= GdipCreateFontFamilyFromName (Tahoma
, NULL
, NULL
);
315 expect (InvalidParameter
, stat
);
317 /* FontFamily must be able to actually find the family.
318 * If it can't, any subsequent calls should fail.
320 stat
= GdipCreateFontFamilyFromName (nonexistent
, NULL
, &family
);
321 expect (FontFamilyNotFound
, stat
);
323 /* Bitmap fonts are not found */
324 stat
= GdipCreateFontFamilyFromName (MSSansSerif
, NULL
, &family
);
325 expect (FontFamilyNotFound
, stat
);
326 if(stat
== Ok
) GdipDeleteFontFamily(family
);
328 stat
= GdipCreateFontFamilyFromName (Tahoma
, NULL
, &family
);
331 stat
= GdipGetFamilyName (family
, itsName
, LANG_NEUTRAL
);
333 expect (0, lstrcmpiW(itsName
, Tahoma
));
337 /* Crashes on Windows XP SP2, Vista, and so Wine as well */
338 stat
= GdipGetFamilyName (family
, NULL
, LANG_NEUTRAL
);
342 /* Make sure we don't read old data */
343 ZeroMemory (itsName
, sizeof(itsName
));
344 stat
= GdipCloneFontFamily(family
, &clonedFontFamily
);
346 GdipDeleteFontFamily(family
);
347 stat
= GdipGetFamilyName(clonedFontFamily
, itsName
, LANG_NEUTRAL
);
349 expect(0, lstrcmpiW(itsName
, Tahoma
));
351 GdipDeleteFontFamily(clonedFontFamily
);
354 static void test_fontfamily_properties (void)
356 GpFontFamily
* FontFamily
= NULL
;
360 stat
= GdipCreateFontFamilyFromName(Tahoma
, NULL
, &FontFamily
);
363 stat
= GdipGetLineSpacing(FontFamily
, FontStyleRegular
, &result
);
365 ok (result
== 2472, "Expected 2472, got %d\n", result
);
367 stat
= GdipGetEmHeight(FontFamily
, FontStyleRegular
, &result
);
369 ok(result
== 2048, "Expected 2048, got %d\n", result
);
371 stat
= GdipGetCellAscent(FontFamily
, FontStyleRegular
, &result
);
373 ok(result
== 2049, "Expected 2049, got %d\n", result
);
375 stat
= GdipGetCellDescent(FontFamily
, FontStyleRegular
, &result
);
377 ok(result
== 423, "Expected 423, got %d\n", result
);
378 GdipDeleteFontFamily(FontFamily
);
380 stat
= GdipCreateFontFamilyFromName(TimesNewRoman
, NULL
, &FontFamily
);
381 if(stat
== FontFamilyNotFound
)
382 skip("Times New Roman not installed\n");
386 stat
= GdipGetLineSpacing(FontFamily
, FontStyleRegular
, &result
);
388 ok(result
== 2355, "Expected 2355, got %d\n", result
);
390 stat
= GdipGetEmHeight(FontFamily
, FontStyleRegular
, &result
);
392 ok(result
== 2048, "Expected 2048, got %d\n", result
);
394 stat
= GdipGetCellAscent(FontFamily
, FontStyleRegular
, &result
);
396 ok(result
== 1825, "Expected 1825, got %d\n", result
);
398 stat
= GdipGetCellDescent(FontFamily
, FontStyleRegular
, &result
);
400 ok(result
== 443, "Expected 443 got %d\n", result
);
401 GdipDeleteFontFamily(FontFamily
);
405 static void check_family(const char* context
, GpFontFamily
*family
, WCHAR
*name
)
411 stat
= GdipGetFamilyName(family
, name
, LANG_NEUTRAL
);
412 ok(stat
== Ok
, "could not get the %s family name: %.8x\n", context
, stat
);
414 stat
= GdipCreateFont(family
, 12, FontStyleRegular
, UnitPixel
, &font
);
415 ok(stat
== Ok
, "could not create a font for the %s family: %.8x\n", context
, stat
);
418 stat
= GdipDeleteFont(font
);
419 ok(stat
== Ok
, "could not delete the %s family font: %.8x\n", context
, stat
);
422 stat
= GdipDeleteFontFamily(family
);
423 ok(stat
== Ok
, "could not delete the %s family: %.8x\n", context
, stat
);
426 static void test_getgenerics (void)
429 GpFontFamily
*family
;
430 WCHAR sansname
[LF_FACESIZE
], serifname
[LF_FACESIZE
], mononame
[LF_FACESIZE
];
431 int missingfonts
= 0;
433 stat
= GdipGetGenericFontFamilySansSerif(&family
);
435 if (stat
== FontFamilyNotFound
)
438 check_family("Sans Serif", family
, sansname
);
440 stat
= GdipGetGenericFontFamilySerif(&family
);
442 if (stat
== FontFamilyNotFound
)
445 check_family("Serif", family
, serifname
);
447 stat
= GdipGetGenericFontFamilyMonospace(&family
);
449 if (stat
== FontFamilyNotFound
)
452 check_family("Monospace", family
, mononame
);
454 if (missingfonts
&& strcmp(winetest_platform
, "wine") == 0)
455 trace("You may need to install either the Microsoft Web Fonts or the Liberation Fonts\n");
457 /* Check that the family names are all different */
458 ok(lstrcmpiW(sansname
, serifname
) != 0, "Sans Serif and Serif families should be different: %s\n", wine_dbgstr_w(sansname
));
459 ok(lstrcmpiW(sansname
, mononame
) != 0, "Sans Serif and Monospace families should be different: %s\n", wine_dbgstr_w(sansname
));
460 ok(lstrcmpiW(serifname
, mononame
) != 0, "Serif and Monospace families should be different: %s\n", wine_dbgstr_w(serifname
));
463 static void test_installedfonts (void)
466 GpFontCollection
* collection
=NULL
;
468 stat
= GdipNewInstalledFontCollection(NULL
);
469 expect (InvalidParameter
, stat
);
471 stat
= GdipNewInstalledFontCollection(&collection
);
473 ok (collection
!= NULL
, "got NULL font collection\n");
476 static void test_heightgivendpi(void)
480 GpFontFamily
* fontfamily
= NULL
;
484 stat
= GdipCreateFontFamilyFromName(Tahoma
, NULL
, &fontfamily
);
487 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitPixel
, &font
);
490 stat
= GdipGetFontHeightGivenDPI(NULL
, 96, &height
);
491 expect(InvalidParameter
, stat
);
493 stat
= GdipGetFontHeightGivenDPI(font
, 96, NULL
);
494 expect(InvalidParameter
, stat
);
496 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
498 expectf(36.210938, height
);
499 GdipDeleteFont(font
);
502 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitWorld
, &font
);
505 stat
= GdipGetFontUnit(font
, &unit
);
507 expect(UnitWorld
, unit
);
509 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
511 expectf(36.210938, height
);
512 GdipDeleteFont(font
);
515 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitPoint
, &font
);
517 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
519 expectf(48.281250, height
);
520 GdipDeleteFont(font
);
523 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitInch
, &font
);
526 stat
= GdipGetFontUnit(font
, &unit
);
528 expect(UnitInch
, unit
);
530 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
532 expectf(3476.250000, height
);
533 GdipDeleteFont(font
);
536 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitDocument
, &font
);
539 stat
= GdipGetFontUnit(font
, &unit
);
541 expect(UnitDocument
, unit
);
543 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
545 expectf(11.587500, height
);
546 GdipDeleteFont(font
);
549 stat
= GdipCreateFont(fontfamily
, 30, FontStyleRegular
, UnitMillimeter
, &font
);
552 stat
= GdipGetFontUnit(font
, &unit
);
554 expect(UnitMillimeter
, unit
);
556 stat
= GdipGetFontHeightGivenDPI(font
, 96, &height
);
558 expectf(136.860245, height
);
559 GdipDeleteFont(font
);
561 GdipDeleteFontFamily(fontfamily
);
564 static int CALLBACK
font_enum_proc(const LOGFONTW
*lfe
, const TEXTMETRICW
*ntme
,
565 DWORD type
, LPARAM lparam
)
567 NEWTEXTMETRICW
*ntm
= (NEWTEXTMETRICW
*)lparam
;
569 if (type
!= TRUETYPE_FONTTYPE
) return 1;
571 *ntm
= *(NEWTEXTMETRICW
*)ntme
;
577 UINT16 em_height
, line_spacing
, ascent
, descent
;
578 REAL font_height
, font_size
;
582 static void gdi_get_font_metrics(LOGFONTW
*lf
, struct font_metrics
*fm
)
587 OUTLINETEXTMETRICW otm
;
590 hdc
= CreateCompatibleDC(0);
592 /* it's the only way to get extended NEWTEXTMETRIC fields */
593 ret
= EnumFontFamiliesExW(hdc
, lf
, font_enum_proc
, (LPARAM
)&ntm
, 0);
594 ok(!ret
, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf
->lfFaceName
));
596 hfont
= CreateFontIndirectW(lf
);
597 SelectObject(hdc
, hfont
);
599 otm
.otmSize
= sizeof(otm
);
600 ret
= GetOutlineTextMetricsW(hdc
, otm
.otmSize
, &otm
);
601 ok(ret
, "GetOutlineTextMetrics failed\n");
606 fm
->lfHeight
= -otm
.otmTextMetrics
.tmAscent
;
607 fm
->line_spacing
= ntm
.ntmCellHeight
;
608 fm
->font_size
= (REAL
)otm
.otmTextMetrics
.tmAscent
;
609 fm
->font_height
= (REAL
)fm
->line_spacing
* fm
->font_size
/ (REAL
)ntm
.ntmSizeEM
;
610 fm
->em_height
= ntm
.ntmSizeEM
;
611 fm
->ascent
= ntm
.ntmSizeEM
;
612 fm
->descent
= ntm
.ntmCellHeight
- ntm
.ntmSizeEM
;
615 static void gdip_get_font_metrics(GpFont
*font
, struct font_metrics
*fm
)
618 GpFontFamily
*family
;
621 stat
= GdipGetFontStyle(font
, &style
);
624 stat
= GdipGetFontHeight(NULL
, NULL
, &fm
->font_height
);
625 expect(InvalidParameter
, stat
);
627 stat
= GdipGetFontHeight(font
, NULL
, NULL
);
628 expect(InvalidParameter
, stat
);
630 stat
= GdipGetFontHeight(font
, NULL
, &fm
->font_height
);
632 stat
= GdipGetFontSize(font
, &fm
->font_size
);
635 fm
->lfHeight
= (INT
)(fm
->font_size
* -1.0);
637 stat
= GdipGetFamily(font
, &family
);
640 stat
= GdipGetEmHeight(family
, style
, &fm
->em_height
);
642 stat
= GdipGetLineSpacing(family
, style
, &fm
->line_spacing
);
644 stat
= GdipGetCellAscent(family
, style
, &fm
->ascent
);
646 stat
= GdipGetCellDescent(family
, style
, &fm
->descent
);
649 GdipDeleteFontFamily(family
);
652 static void cmp_font_metrics(struct font_metrics
*fm1
, struct font_metrics
*fm2
, int line
)
654 ok_(__FILE__
, line
)(fm1
->lfHeight
== fm2
->lfHeight
, "lfHeight %d != %d\n", fm1
->lfHeight
, fm2
->lfHeight
);
655 ok_(__FILE__
, line
)(fm1
->em_height
== fm2
->em_height
, "em_height %u != %u\n", fm1
->em_height
, fm2
->em_height
);
656 ok_(__FILE__
, line
)(fm1
->line_spacing
== fm2
->line_spacing
, "line_spacing %u != %u\n", fm1
->line_spacing
, fm2
->line_spacing
);
657 ok_(__FILE__
, line
)(abs(fm1
->ascent
- fm2
->ascent
) <= 1, "ascent %u != %u\n", fm1
->ascent
, fm2
->ascent
);
658 ok_(__FILE__
, line
)(abs(fm1
->descent
- fm2
->descent
) <= 1, "descent %u != %u\n", fm1
->descent
, fm2
->descent
);
659 ok(fm1
->font_height
> 0.0, "fm1->font_height should be positive, got %f\n", fm1
->font_height
);
660 ok(fm2
->font_height
> 0.0, "fm2->font_height should be positive, got %f\n", fm2
->font_height
);
661 ok_(__FILE__
, line
)(fm1
->font_height
== fm2
->font_height
, "font_height %f != %f\n", fm1
->font_height
, fm2
->font_height
);
662 ok(fm1
->font_size
> 0.0, "fm1->font_size should be positive, got %f\n", fm1
->font_size
);
663 ok(fm2
->font_size
> 0.0, "fm2->font_size should be positive, got %f\n", fm2
->font_size
);
664 ok_(__FILE__
, line
)(fm1
->font_size
== fm2
->font_size
, "font_size %f != %f\n", fm1
->font_size
, fm2
->font_size
);
667 static void test_font_metrics(void)
671 GpFontFamily
*family
;
672 GpGraphics
*graphics
;
675 struct font_metrics fm_gdi
, fm_gdip
;
678 hdc
= CreateCompatibleDC(0);
679 stat
= GdipCreateFromHDC(hdc
, &graphics
);
682 memset(&lf
, 0, sizeof(lf
));
685 lstrcpyW(lf
.lfFaceName
, Tahoma
);
687 stat
= GdipCreateFontFromLogfontW(hdc
, &lf
, &font
);
690 stat
= GdipGetFontUnit(font
, &unit
);
692 expect(UnitWorld
, unit
);
694 gdip_get_font_metrics(font
, &fm_gdip
);
696 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
697 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
698 fm_gdip
.em_height
, fm_gdip
.line_spacing
, fm_gdip
.ascent
, fm_gdip
.descent
,
699 fm_gdip
.font_height
, fm_gdip
.font_size
);
701 gdi_get_font_metrics(&lf
, &fm_gdi
);
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
);
708 cmp_font_metrics(&fm_gdip
, &fm_gdi
, __LINE__
);
710 stat
= GdipGetLogFontW(font
, graphics
, &lf
);
712 ok(lf
.lfHeight
< 0, "lf.lfHeight should be negative, got %d\n", lf
.lfHeight
);
713 gdi_get_font_metrics(&lf
, &fm_gdi
);
715 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
716 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
717 fm_gdi
.em_height
, fm_gdi
.line_spacing
, fm_gdi
.ascent
, fm_gdi
.descent
,
718 fm_gdi
.font_height
, fm_gdi
.font_size
);
719 ok((REAL
)lf
.lfHeight
* -1.0 == fm_gdi
.font_size
, "expected %f, got %f\n", (REAL
)lf
.lfHeight
* -1.0, fm_gdi
.font_size
);
721 cmp_font_metrics(&fm_gdip
, &fm_gdi
, __LINE__
);
723 GdipDeleteFont(font
);
726 lstrcpyW(lf
.lfFaceName
, Tahoma
);
728 stat
= GdipCreateFontFromLogfontW(hdc
, &lf
, &font
);
731 stat
= GdipGetFontUnit(font
, &unit
);
733 expect(UnitWorld
, unit
);
735 gdip_get_font_metrics(font
, &fm_gdip
);
737 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
738 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
739 fm_gdip
.em_height
, fm_gdip
.line_spacing
, fm_gdip
.ascent
, fm_gdip
.descent
,
740 fm_gdip
.font_height
, fm_gdip
.font_size
);
742 gdi_get_font_metrics(&lf
, &fm_gdi
);
744 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
745 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
746 fm_gdi
.em_height
, fm_gdi
.line_spacing
, fm_gdi
.ascent
, fm_gdi
.descent
,
747 fm_gdi
.font_height
, fm_gdi
.font_size
);
749 cmp_font_metrics(&fm_gdip
, &fm_gdi
, __LINE__
);
751 stat
= GdipGetLogFontW(font
, graphics
, &lf
);
753 ok(lf
.lfHeight
< 0, "lf.lfHeight should be negative, got %d\n", lf
.lfHeight
);
754 gdi_get_font_metrics(&lf
, &fm_gdi
);
756 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
757 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
758 fm_gdi
.em_height
, fm_gdi
.line_spacing
, fm_gdi
.ascent
, fm_gdi
.descent
,
759 fm_gdi
.font_height
, fm_gdi
.font_size
);
760 ok((REAL
)lf
.lfHeight
* -1.0 == fm_gdi
.font_size
, "expected %f, got %f\n", (REAL
)lf
.lfHeight
* -1.0, fm_gdi
.font_size
);
762 cmp_font_metrics(&fm_gdip
, &fm_gdi
, __LINE__
);
764 GdipDeleteFont(font
);
766 stat
= GdipCreateFontFamilyFromName(Tahoma
, NULL
, &family
);
770 stat
= GdipCreateFont(family
, 13.0, FontStyleRegular
, UnitPixel
, &font
);
773 gdip_get_font_metrics(font
, &fm_gdip
);
775 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
776 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
777 fm_gdip
.em_height
, fm_gdip
.line_spacing
, fm_gdip
.ascent
, fm_gdip
.descent
,
778 fm_gdip
.font_height
, fm_gdip
.font_size
);
780 stat
= GdipGetLogFontW(font
, graphics
, &lf
);
782 ok(lf
.lfHeight
< 0, "lf.lfHeight should be negative, got %d\n", lf
.lfHeight
);
783 gdi_get_font_metrics(&lf
, &fm_gdi
);
785 trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
786 wine_dbgstr_w(lf
.lfFaceName
), lf
.lfHeight
,
787 fm_gdi
.em_height
, fm_gdi
.line_spacing
, fm_gdi
.ascent
, fm_gdi
.descent
,
788 fm_gdi
.font_height
, fm_gdi
.font_size
);
789 ok((REAL
)lf
.lfHeight
* -1.0 == fm_gdi
.font_size
, "expected %f, got %f\n", (REAL
)lf
.lfHeight
* -1.0, fm_gdi
.font_size
);
791 cmp_font_metrics(&fm_gdip
, &fm_gdi
, __LINE__
);
793 stat
= GdipGetLogFontW(font
, NULL
, &lf
);
794 expect(InvalidParameter
, stat
);
796 GdipDeleteFont(font
);
798 stat
= GdipCreateFont(family
, -13.0, FontStyleRegular
, UnitPixel
, &font
);
799 expect(InvalidParameter
, stat
);
801 GdipDeleteFontFamily(family
);
803 GdipDeleteGraphics(graphics
);
807 static void test_font_substitution(void)
809 WCHAR ms_shell_dlg
[LF_FACESIZE
];
810 char fallback_font
[LF_FACESIZE
];
815 GpGraphics
*graphics
;
817 GpFontFamily
*family
;
820 hdc
= CreateCompatibleDC(0);
821 status
= GdipCreateFromHDC(hdc
, &graphics
);
824 hfont
= GetStockObject(DEFAULT_GUI_FONT
);
825 ok(hfont
!= 0, "GetStockObject(DEFAULT_GUI_FONT) failed\n");
827 memset(&lf
, 0xfe, sizeof(lf
));
828 ret
= GetObjectA(hfont
, sizeof(lf
), &lf
);
829 ok(ret
== sizeof(lf
), "GetObject failed\n");
830 ok(!lstrcmpA(lf
.lfFaceName
, "MS Shell Dlg"), "wrong face name %s\n", lf
.lfFaceName
);
831 MultiByteToWideChar(CP_ACP
, 0, lf
.lfFaceName
, -1, ms_shell_dlg
, LF_FACESIZE
);
833 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
835 memset(&lf
, 0xfe, sizeof(lf
));
836 status
= GdipGetLogFontA(font
, graphics
, &lf
);
838 ok(!lstrcmpA(lf
.lfFaceName
, "Microsoft Sans Serif") ||
839 !lstrcmpA(lf
.lfFaceName
, "Tahoma"), "wrong face name %s\n", lf
.lfFaceName
);
840 GdipDeleteFont(font
);
842 status
= GdipCreateFontFamilyFromName(ms_shell_dlg
, NULL
, &family
);
844 status
= GdipCreateFont(family
, 12, FontStyleRegular
, UnitPoint
, &font
);
846 memset(&lf
, 0xfe, sizeof(lf
));
847 status
= GdipGetLogFontA(font
, graphics
, &lf
);
849 ok(!lstrcmpA(lf
.lfFaceName
, "Microsoft Sans Serif") ||
850 !lstrcmpA(lf
.lfFaceName
, "Tahoma"), "wrong face name %s\n", lf
.lfFaceName
);
851 GdipDeleteFont(font
);
852 GdipDeleteFontFamily(family
);
854 status
= GdipCreateFontFamilyFromName(nonexistent
, NULL
, &family
);
855 ok(status
== FontFamilyNotFound
, "expected FontFamilyNotFound, got %d\n", status
);
857 /* nonexistent fonts fallback to Arial, or something else if it's missing */
858 strcpy(lf
.lfFaceName
,"Arial");
859 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
861 status
= GdipGetLogFontA(font
, graphics
, &lf
);
863 strcpy(fallback_font
,lf
.lfFaceName
);
864 trace("fallback font %s\n", fallback_font
);
865 GdipDeleteFont(font
);
867 lstrcpyA(lf
.lfFaceName
, "ThisFontShouldNotExist");
868 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
870 memset(&lf
, 0xfe, sizeof(lf
));
871 status
= GdipGetLogFontA(font
, graphics
, &lf
);
873 ok(!lstrcmpA(lf
.lfFaceName
, fallback_font
), "wrong face name %s / %s\n", lf
.lfFaceName
, fallback_font
);
874 GdipDeleteFont(font
);
877 lf
.lfFaceName
[0] = 0;
878 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
880 memset(&lf
, 0xfe, sizeof(lf
));
881 status
= GdipGetLogFontA(font
, graphics
, &lf
);
883 ok(!lstrcmpA(lf
.lfFaceName
, fallback_font
), "wrong face name %s / %s\n", lf
.lfFaceName
, fallback_font
);
884 GdipDeleteFont(font
);
886 /* zeroing out lfWeight and lfCharSet leads to font creation failure */
889 lstrcpyA(lf
.lfFaceName
, "ThisFontShouldNotExist");
891 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
893 ok(status
== NotTrueTypeFont
|| broken(status
== FileNotFound
), /* before XP */
894 "expected NotTrueTypeFont, got %d\n", status
);
895 /* FIXME: remove when wine is fixed */
896 if (font
) GdipDeleteFont(font
);
899 lf
.lfFaceName
[0] = 0;
901 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
903 ok(status
== NotTrueTypeFont
|| broken(status
== FileNotFound
), /* before XP */
904 "expected NotTrueTypeFont, got %d\n", status
);
905 /* FIXME: remove when wine is fixed */
906 if (font
) GdipDeleteFont(font
);
908 GdipDeleteGraphics(graphics
);
912 static void test_font_transform(void)
914 static const WCHAR string
[] = { 'A',0 };
919 GpGraphics
*graphics
;
921 GpStringFormat
*format
, *typographic
;
922 PointF pos
[1] = { { 0,0 } };
923 REAL height
, margin_y
;
926 hdc
= CreateCompatibleDC(0);
927 status
= GdipCreateFromHDC(hdc
, &graphics
);
930 status
= GdipSetPageUnit(graphics
, UnitPixel
);
933 status
= GdipCreateStringFormat(0, LANG_NEUTRAL
, &format
);
935 status
= GdipStringFormatGetGenericTypographic(&typographic
);
938 memset(&lf
, 0, sizeof(lf
));
939 lstrcpyA(lf
.lfFaceName
, "Tahoma");
942 status
= GdipCreateFontFromLogfontA(hdc
, &lf
, &font
);
945 margin_y
= 100.0 / 8.0;
947 /* identity matrix */
948 status
= GdipCreateMatrix(&matrix
);
950 status
= GdipSetWorldTransform(graphics
, matrix
);
952 status
= GdipGetLogFontA(font
, graphics
, &lf
);
954 expect(-100, lf
.lfHeight
);
955 expect(0, lf
.lfWidth
);
956 expect(0, lf
.lfEscapement
);
957 expect(0, lf
.lfOrientation
);
958 status
= GdipGetFontHeight(font
, graphics
, &height
);
960 expectf(120.703125, height
);
961 set_rect_empty(&rect
);
962 set_rect_empty(&bounds
);
963 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, format
, &bounds
, NULL
, NULL
);
965 expectf(0.0, bounds
.X
);
966 expectf(0.0, bounds
.Y
);
968 expectf(height
+ margin_y
, bounds
.Height
);
969 set_rect_empty(&rect
);
970 set_rect_empty(&bounds
);
971 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, typographic
, &bounds
, NULL
, NULL
);
973 expectf(0.0, bounds
.X
);
974 expectf(0.0, bounds
.Y
);
975 expectf_(height
, bounds
.Height
, 1.0);
976 set_rect_empty(&bounds
);
977 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
978 DriverStringOptionsCmapLookup
, NULL
, &bounds
);
980 expectf(0.0, bounds
.X
);
981 expectf_(-100.0, bounds
.Y
, 0.05);
982 expectf_(height
, bounds
.Height
, 0.5);
983 set_rect_empty(&bounds
);
984 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
985 DriverStringOptionsCmapLookup
, matrix
, &bounds
);
987 expectf(0.0, bounds
.X
);
988 expectf_(-100.0, bounds
.Y
, 0.05);
989 expectf_(height
, bounds
.Height
, 0.5);
992 status
= GdipScaleMatrix(matrix
, 2.0, 3.0, MatrixOrderAppend
);
994 status
= GdipSetWorldTransform(graphics
, matrix
);
996 status
= GdipGetLogFontA(font
, graphics
, &lf
);
998 expect(-300, lf
.lfHeight
);
999 expect(0, lf
.lfWidth
);
1000 expect(0, lf
.lfEscapement
);
1001 expect(0, lf
.lfOrientation
);
1002 status
= GdipGetFontHeight(font
, graphics
, &height
);
1004 expectf(120.703125, height
);
1005 set_rect_empty(&rect
);
1006 set_rect_empty(&bounds
);
1007 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, format
, &bounds
, NULL
, NULL
);
1009 expectf(0.0, bounds
.X
);
1010 expectf(0.0, bounds
.Y
);
1012 expectf(height
+ margin_y
, bounds
.Height
);
1013 set_rect_empty(&rect
);
1014 set_rect_empty(&bounds
);
1015 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, typographic
, &bounds
, NULL
, NULL
);
1017 expectf(0.0, bounds
.X
);
1018 expectf(0.0, bounds
.Y
);
1019 expectf_(height
, bounds
.Height
, 0.05);
1020 set_rect_empty(&bounds
);
1021 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1022 DriverStringOptionsCmapLookup
, NULL
, &bounds
);
1024 expectf(0.0, bounds
.X
);
1025 expectf_(-100.0, bounds
.Y
, 0.05);
1026 expectf_(height
, bounds
.Height
, 0.2);
1027 set_rect_empty(&bounds
);
1028 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1029 DriverStringOptionsCmapLookup
, matrix
, &bounds
);
1031 expectf(0.0, bounds
.X
);
1033 expectf_(-300.0, bounds
.Y
, 0.15);
1035 expectf(height
* 3.0, bounds
.Height
);
1037 /* scale + ratate matrix */
1038 status
= GdipRotateMatrix(matrix
, 45.0, MatrixOrderAppend
);
1040 status
= GdipSetWorldTransform(graphics
, matrix
);
1042 status
= GdipGetLogFontA(font
, graphics
, &lf
);
1044 expect(-300, lf
.lfHeight
);
1045 expect(0, lf
.lfWidth
);
1046 expect_(3151, lf
.lfEscapement
, 1);
1047 expect_(3151, lf
.lfOrientation
, 1);
1048 status
= GdipGetFontHeight(font
, graphics
, &height
);
1050 expectf(120.703125, height
);
1051 set_rect_empty(&rect
);
1052 set_rect_empty(&bounds
);
1053 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, format
, &bounds
, NULL
, NULL
);
1055 expectf(0.0, bounds
.X
);
1056 expectf(0.0, bounds
.Y
);
1058 expectf(height
+ margin_y
, bounds
.Height
);
1059 set_rect_empty(&rect
);
1060 set_rect_empty(&bounds
);
1061 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, typographic
, &bounds
, NULL
, NULL
);
1063 expectf(0.0, bounds
.X
);
1064 expectf(0.0, bounds
.Y
);
1065 expectf_(height
, bounds
.Height
, 0.05);
1066 set_rect_empty(&bounds
);
1067 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1068 DriverStringOptionsCmapLookup
, NULL
, &bounds
);
1070 expectf(0.0, bounds
.X
);
1071 expectf_(-100.0, bounds
.Y
, 0.05);
1072 expectf_(height
, bounds
.Height
, 0.2);
1073 set_rect_empty(&bounds
);
1074 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1075 DriverStringOptionsCmapLookup
, matrix
, &bounds
);
1078 expectf_(-43.814377, bounds
.X
, 0.05);
1080 expectf_(-212.235611, bounds
.Y
, 0.05);
1082 expectf_(340.847534, bounds
.Height
, 0.05);
1084 /* scale + ratate + shear matrix */
1085 status
= GdipShearMatrix(matrix
, 4.0, 5.0, MatrixOrderAppend
);
1087 status
= GdipSetWorldTransform(graphics
, matrix
);
1089 status
= GdipGetLogFontA(font
, graphics
, &lf
);
1092 expect(1032, lf
.lfHeight
);
1093 expect(0, lf
.lfWidth
);
1094 expect_(3099, lf
.lfEscapement
, 1);
1095 expect_(3099, lf
.lfOrientation
, 1);
1096 status
= GdipGetFontHeight(font
, graphics
, &height
);
1098 expectf(120.703125, height
);
1099 set_rect_empty(&rect
);
1100 set_rect_empty(&bounds
);
1101 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, format
, &bounds
, NULL
, NULL
);
1103 expectf(0.0, bounds
.X
);
1104 expectf(0.0, bounds
.Y
);
1106 expectf(height
+ margin_y
, bounds
.Height
);
1107 set_rect_empty(&rect
);
1108 set_rect_empty(&bounds
);
1109 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, typographic
, &bounds
, NULL
, NULL
);
1111 expectf(0.0, bounds
.X
);
1112 expectf(0.0, bounds
.Y
);
1113 expectf_(height
, bounds
.Height
, 0.2);
1114 set_rect_empty(&bounds
);
1115 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1116 DriverStringOptionsCmapLookup
, NULL
, &bounds
);
1118 expectf(0.0, bounds
.X
);
1119 expectf_(-100.0, bounds
.Y
, 0.2);
1120 expectf_(height
, bounds
.Height
, 0.2);
1121 set_rect_empty(&bounds
);
1122 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1123 DriverStringOptionsCmapLookup
, matrix
, &bounds
);
1126 expectf_(-636.706848, bounds
.X
, 0.05);
1128 expectf_(-175.257523, bounds
.Y
, 0.05);
1130 expectf_(1532.984985, bounds
.Height
, 0.05);
1132 /* scale + ratate + shear + translate matrix */
1133 status
= GdipTranslateMatrix(matrix
, 10.0, 20.0, MatrixOrderAppend
);
1135 status
= GdipSetWorldTransform(graphics
, matrix
);
1137 status
= GdipGetLogFontA(font
, graphics
, &lf
);
1140 expect(1032, lf
.lfHeight
);
1141 expect(0, lf
.lfWidth
);
1142 expect_(3099, lf
.lfEscapement
, 1);
1143 expect_(3099, lf
.lfOrientation
, 1);
1144 status
= GdipGetFontHeight(font
, graphics
, &height
);
1146 expectf(120.703125, height
);
1147 set_rect_empty(&rect
);
1148 set_rect_empty(&bounds
);
1149 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, format
, &bounds
, NULL
, NULL
);
1151 expectf(0.0, bounds
.X
);
1152 expectf(0.0, bounds
.Y
);
1154 expectf(height
+ margin_y
, bounds
.Height
);
1155 set_rect_empty(&rect
);
1156 set_rect_empty(&bounds
);
1157 status
= GdipMeasureString(graphics
, string
, -1, font
, &rect
, typographic
, &bounds
, NULL
, NULL
);
1159 expectf(0.0, bounds
.X
);
1160 expectf(0.0, bounds
.Y
);
1161 expectf_(height
, bounds
.Height
, 0.1);
1162 set_rect_empty(&bounds
);
1163 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1164 DriverStringOptionsCmapLookup
, NULL
, &bounds
);
1166 expectf(0.0, bounds
.X
);
1167 expectf_(-100.0, bounds
.Y
, 0.2);
1168 expectf_(height
, bounds
.Height
, 0.2);
1169 set_rect_empty(&bounds
);
1170 status
= GdipMeasureDriverString(graphics
, (const UINT16
*)string
, -1, font
, pos
,
1171 DriverStringOptionsCmapLookup
, matrix
, &bounds
);
1174 expectf_(-626.706848, bounds
.X
, 0.05);
1176 expectf_(-155.257523, bounds
.Y
, 0.05);
1178 expectf_(1532.984985, bounds
.Height
, 0.05);
1180 GdipDeleteMatrix(matrix
);
1181 GdipDeleteFont(font
);
1182 GdipDeleteGraphics(graphics
);
1183 GdipDeleteStringFormat(typographic
);
1184 GdipDeleteStringFormat(format
);
1188 static void test_GdipGetFontCollectionFamilyList(void)
1190 GpFontFamily
*family
, *family2
;
1191 GpFontCollection
*collection
;
1195 status
= GdipNewInstalledFontCollection(&collection
);
1196 ok(status
== Ok
, "Failed to get system collection, status %d.\n", status
);
1199 status
= GdipGetFontCollectionFamilyCount(collection
, &count
);
1200 ok(status
== Ok
, "Failed to get family count, status %d.\n", status
);
1201 ok(count
> 0, "Unexpected empty collection.\n");
1203 status
= GdipGetFontCollectionFamilyList(NULL
, 0, NULL
, NULL
);
1204 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1207 status
= GdipGetFontCollectionFamilyList(NULL
, 0, NULL
, &found
);
1208 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1209 ok(found
== 123, "Unexpected list count %d.\n", found
);
1211 status
= GdipGetFontCollectionFamilyList(collection
, 0, NULL
, NULL
);
1212 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1215 status
= GdipGetFontCollectionFamilyList(collection
, 0, NULL
, &found
);
1216 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1217 ok(found
== 123, "Unexpected list count %d.\n", found
);
1220 status
= GdipGetFontCollectionFamilyList(collection
, 1, NULL
, &found
);
1221 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1222 ok(found
== 123, "Unexpected list count %d.\n", found
);
1226 status
= GdipGetFontCollectionFamilyList(collection
, 1, &family
, &found
);
1227 ok(status
== Ok
, "Failed to get family list, status %d.\n", status
);
1228 ok(found
== 1, "Unexpected list count %d.\n", found
);
1229 ok(family
!= NULL
, "Expected family instance.\n");
1233 status
= GdipGetFontCollectionFamilyList(collection
, 1, &family2
, &found
);
1234 ok(status
== Ok
, "Failed to get family list, status %d.\n", status
);
1235 ok(found
== 1, "Unexpected list count %d.\n", found
);
1236 ok(family2
!= family
, "Unexpected family instance.\n");
1238 GdipDeleteFontFamily(family
);
1239 GdipDeleteFontFamily(family2
);
1242 static void test_GdipGetFontCollectionFamilyCount(void)
1244 GpFontCollection
*collection
;
1248 status
= GdipGetFontCollectionFamilyCount(NULL
, NULL
);
1249 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1252 status
= GdipGetFontCollectionFamilyCount(NULL
, &count
);
1253 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1254 ok(count
== 123, "Unexpected family count %d.\n", count
);
1256 status
= GdipNewInstalledFontCollection(&collection
);
1257 ok(status
== Ok
, "Failed to get system collection, status %d.\n", status
);
1259 status
= GdipGetFontCollectionFamilyCount(collection
, NULL
);
1260 ok(status
== InvalidParameter
, "Unexpected status %d.\n", status
);
1265 struct GdiplusStartupInput gdiplusStartupInput
;
1266 ULONG_PTR gdiplusToken
;
1268 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
1270 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1271 hmsvcrt
= LoadLibraryA("msvcrt");
1272 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
1273 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
1275 gdiplusStartupInput
.GdiplusVersion
= 1;
1276 gdiplusStartupInput
.DebugEventCallback
= NULL
;
1277 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
1278 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
1280 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
1283 test_font_transform();
1284 test_font_substitution();
1285 test_font_metrics();
1289 test_fontfamily_properties();
1291 test_installedfonts();
1292 test_heightgivendpi();
1293 test_GdipGetFontCollectionFamilyList();
1294 test_GdipGetFontCollectionFamilyCount();
1296 GdiplusShutdown(gdiplusToken
);