1c2c66affSColin Finck /*
2c2c66affSColin Finck * Unit test suite for fonts
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright (C) 2007 Google (Evan Stade)
5c2c66affSColin Finck * Copyright (C) 2012 Dmitry Timoshkov
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck */
21c2c66affSColin Finck
22e3f6657fSAmine Khaldi #include <math.h>
23e3f6657fSAmine Khaldi
24e3f6657fSAmine Khaldi #include "objbase.h"
25e3f6657fSAmine Khaldi #include "gdiplus.h"
26e3f6657fSAmine Khaldi #include "wine/test.h"
27c2c66affSColin Finck
28c2c66affSColin Finck #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
29c2c66affSColin Finck #define expect_(expected, got, precision) ok(abs((expected) - (got)) <= (precision), "Expected %d, got %d\n", (expected), (got))
30c2c66affSColin Finck #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
31c2c66affSColin Finck #define expectf(expected, got) expectf_((expected), (got), 0.001)
32c2c66affSColin Finck
33c2c66affSColin Finck 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'};
34c2c66affSColin Finck static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
35c2c66affSColin Finck static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
36c2c66affSColin Finck static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
37c2c66affSColin Finck
set_rect_empty(RectF * rc)38c2c66affSColin Finck static void set_rect_empty(RectF *rc)
39c2c66affSColin Finck {
40c2c66affSColin Finck rc->X = 0.0;
41c2c66affSColin Finck rc->Y = 0.0;
42c2c66affSColin Finck rc->Width = 0.0;
43c2c66affSColin Finck rc->Height = 0.0;
44c2c66affSColin Finck }
45c2c66affSColin Finck
create_testfontfile(const WCHAR * filename,int resource,WCHAR pathW[MAX_PATH])4670c9f307SAmine Khaldi static void create_testfontfile(const WCHAR *filename, int resource, WCHAR pathW[MAX_PATH])
4770c9f307SAmine Khaldi {
4870c9f307SAmine Khaldi DWORD written;
4970c9f307SAmine Khaldi HANDLE file;
5070c9f307SAmine Khaldi HRSRC res;
5170c9f307SAmine Khaldi void *ptr;
5270c9f307SAmine Khaldi
5370c9f307SAmine Khaldi GetTempPathW(MAX_PATH, pathW);
5470c9f307SAmine Khaldi lstrcatW(pathW, filename);
5570c9f307SAmine Khaldi
5670c9f307SAmine Khaldi file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
5770c9f307SAmine Khaldi ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n", wine_dbgstr_w(pathW), GetLastError());
5870c9f307SAmine Khaldi
5970c9f307SAmine Khaldi res = FindResourceA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(resource), (LPCSTR)RT_RCDATA);
6070c9f307SAmine Khaldi ok(res != 0, "couldn't find resource\n");
6170c9f307SAmine Khaldi ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
6270c9f307SAmine Khaldi WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res), &written, NULL);
6370c9f307SAmine Khaldi ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n");
6470c9f307SAmine Khaldi CloseHandle(file);
6570c9f307SAmine Khaldi }
6670c9f307SAmine Khaldi
6770c9f307SAmine Khaldi #define DELETE_FONTFILE(filename) _delete_testfontfile(filename, __LINE__)
_delete_testfontfile(const WCHAR * filename,int line)6870c9f307SAmine Khaldi static void _delete_testfontfile(const WCHAR *filename, int line)
6970c9f307SAmine Khaldi {
7070c9f307SAmine Khaldi BOOL ret = DeleteFileW(filename);
7170c9f307SAmine Khaldi ok_(__FILE__,line)(ret, "failed to delete file %s, error %d\n", wine_dbgstr_w(filename), GetLastError());
7270c9f307SAmine Khaldi }
7370c9f307SAmine Khaldi
test_long_name(void)7470c9f307SAmine Khaldi static void test_long_name(void)
7570c9f307SAmine Khaldi {
7670c9f307SAmine Khaldi WCHAR path[MAX_PATH];
7770c9f307SAmine Khaldi static const WCHAR path_longname[] = {'w','i','n','e','_','l','o','n','g','n','a','m','e','.','t','t','f',0};
7870c9f307SAmine Khaldi GpStatus stat;
7970c9f307SAmine Khaldi GpFontCollection *fonts;
8070c9f307SAmine Khaldi INT num_families;
8170c9f307SAmine Khaldi GpFontFamily *family;
8270c9f307SAmine Khaldi WCHAR family_name[LF_FACESIZE];
8370c9f307SAmine Khaldi GpFont *font;
8470c9f307SAmine Khaldi
8570c9f307SAmine Khaldi stat = GdipNewPrivateFontCollection(&fonts);
8670c9f307SAmine Khaldi ok(stat == Ok, "GdipNewPrivateFontCollection failed: %d\n", stat);
8770c9f307SAmine Khaldi
8870c9f307SAmine Khaldi create_testfontfile(path_longname, 1, path);
8970c9f307SAmine Khaldi
9070c9f307SAmine Khaldi stat = GdipPrivateAddFontFile(fonts, path);
9170c9f307SAmine Khaldi ok(stat == Ok, "GdipPrivateAddFontFile failed: %d\n", stat);
9270c9f307SAmine Khaldi
9370c9f307SAmine Khaldi stat = GdipGetFontCollectionFamilyCount(fonts, &num_families);
9470c9f307SAmine Khaldi ok(stat == Ok, "GdipGetFontCollectionFamilyCount failed: %d\n", stat);
9570c9f307SAmine Khaldi
9670c9f307SAmine Khaldi ok(num_families == 1, "expected num_families to be 1, got %d\n", num_families);
9770c9f307SAmine Khaldi
9870c9f307SAmine Khaldi stat = GdipGetFontCollectionFamilyList(fonts, num_families, &family, &num_families);
9970c9f307SAmine Khaldi ok(stat == Ok, "GdipGetFontCollectionFamilyList failed: %d\n", stat);
10070c9f307SAmine Khaldi
10170c9f307SAmine Khaldi stat = GdipGetFamilyName(family, family_name, LANG_NEUTRAL);
10270c9f307SAmine Khaldi ok(stat == Ok, "GdipGetFamilyName failed: %d\n", stat);
10370c9f307SAmine Khaldi
10470c9f307SAmine Khaldi stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font);
10570c9f307SAmine Khaldi ok(stat == Ok, "GdipCreateFont failed: %d\n", stat);
10670c9f307SAmine Khaldi
10770c9f307SAmine Khaldi /* Cleanup */
10870c9f307SAmine Khaldi
10970c9f307SAmine Khaldi stat = GdipDeleteFont(font);
11070c9f307SAmine Khaldi ok(stat == Ok, "GdipDeleteFont failed: %d\n", stat);
11170c9f307SAmine Khaldi
11270c9f307SAmine Khaldi stat = GdipDeletePrivateFontCollection(&fonts);
11370c9f307SAmine Khaldi ok(stat == Ok, "GdipDeletePrivateFontCollection failed: %d\n", stat);
11470c9f307SAmine Khaldi
11570c9f307SAmine Khaldi DELETE_FONTFILE(path);
11670c9f307SAmine Khaldi }
11770c9f307SAmine Khaldi
test_createfont(void)118c2c66affSColin Finck static void test_createfont(void)
119c2c66affSColin Finck {
120c2c66affSColin Finck GpFontFamily* fontfamily = NULL, *fontfamily2;
121c2c66affSColin Finck GpFont* font = NULL;
122c2c66affSColin Finck GpStatus stat;
123c2c66affSColin Finck Unit unit;
124c2c66affSColin Finck UINT i;
125c2c66affSColin Finck REAL size;
126c2c66affSColin Finck WCHAR familyname[LF_FACESIZE];
127c2c66affSColin Finck
128c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily);
129c2c66affSColin Finck expect (FontFamilyNotFound, stat);
130c2c66affSColin Finck stat = GdipDeleteFont(font);
131c2c66affSColin Finck expect (InvalidParameter, stat);
132c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
133c2c66affSColin Finck expect (Ok, stat);
134c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
135c2c66affSColin Finck expect (Ok, stat);
136c2c66affSColin Finck stat = GdipGetFontUnit (font, &unit);
137c2c66affSColin Finck expect (Ok, stat);
138c2c66affSColin Finck expect (UnitPoint, unit);
139c2c66affSColin Finck
140c2c66affSColin Finck stat = GdipGetFamily(font, &fontfamily2);
141c2c66affSColin Finck expect(Ok, stat);
142c2c66affSColin Finck stat = GdipGetFamilyName(fontfamily2, familyname, 0);
143c2c66affSColin Finck expect(Ok, stat);
144c2c66affSColin Finck ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
145c2c66affSColin Finck wine_dbgstr_w(familyname));
146c2c66affSColin Finck stat = GdipDeleteFontFamily(fontfamily2);
147c2c66affSColin Finck expect(Ok, stat);
148c2c66affSColin Finck
149c2c66affSColin Finck /* Test to see if returned size is based on unit (it's not) */
150c2c66affSColin Finck GdipGetFontSize(font, &size);
151c2c66affSColin Finck ok (size == 12, "Expected 12, got %f\n", size);
152c2c66affSColin Finck GdipDeleteFont(font);
153c2c66affSColin Finck
154c2c66affSColin Finck /* Make sure everything is converted correctly for all Units */
155c2c66affSColin Finck for (i = UnitWorld; i <=UnitMillimeter; i++)
156c2c66affSColin Finck {
157c2c66affSColin Finck if (i == UnitDisplay) continue; /* Crashes WindowsXP, wtf? */
15870c9f307SAmine Khaldi stat = GdipCreateFont(fontfamily, 24, FontStyleRegular, i, &font);
15970c9f307SAmine Khaldi expect(Ok, stat);
160c2c66affSColin Finck GdipGetFontSize (font, &size);
161c2c66affSColin Finck ok (size == 24, "Expected 24, got %f (with unit: %d)\n", size, i);
162*7d57324dSAmine Khaldi stat = GdipGetFontUnit (font, &unit);
163*7d57324dSAmine Khaldi ok (stat == Ok, "Failed to get font unit, %d.\n", stat);
164c2c66affSColin Finck expect (i, unit);
165c2c66affSColin Finck GdipDeleteFont(font);
166c2c66affSColin Finck }
167c2c66affSColin Finck
168c2c66affSColin Finck GdipDeleteFontFamily(fontfamily);
169c2c66affSColin Finck }
170c2c66affSColin Finck
test_logfont(void)171c2c66affSColin Finck static void test_logfont(void)
172c2c66affSColin Finck {
173c2c66affSColin Finck LOGFONTA lfa, lfa2;
174c2c66affSColin Finck GpFont *font;
175c2c66affSColin Finck GpFontFamily *family;
176c2c66affSColin Finck GpStatus stat;
177c2c66affSColin Finck GpGraphics *graphics;
178c2c66affSColin Finck HDC hdc = GetDC(0);
179c2c66affSColin Finck INT style;
180c2c66affSColin Finck REAL rval;
181c2c66affSColin Finck UINT16 em_height, line_spacing;
182c2c66affSColin Finck Unit unit;
183c2c66affSColin Finck
18470c9f307SAmine Khaldi stat = GdipCreateFromHDC(hdc, &graphics);
18570c9f307SAmine Khaldi expect(Ok, stat);
186c2c66affSColin Finck
187c2c66affSColin Finck memset(&lfa, 0, sizeof(LOGFONTA));
188c2c66affSColin Finck memset(&lfa2, 0xff, sizeof(LOGFONTA));
189c2c66affSColin Finck lstrcpyA(lfa.lfFaceName, "Tahoma");
190c2c66affSColin Finck
191c2c66affSColin Finck stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
192c2c66affSColin Finck expect(Ok, stat);
193c2c66affSColin Finck stat = GdipGetLogFontA(font, graphics, &lfa2);
194c2c66affSColin Finck expect(Ok, stat);
195c2c66affSColin Finck
196c2c66affSColin Finck ok(lfa2.lfHeight < 0, "Expected negative height\n");
197c2c66affSColin Finck expect(0, lfa2.lfWidth);
198c2c66affSColin Finck expect(0, lfa2.lfEscapement);
199c2c66affSColin Finck expect(0, lfa2.lfOrientation);
200c2c66affSColin Finck ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
201c2c66affSColin Finck expect(0, lfa2.lfItalic);
202c2c66affSColin Finck expect(0, lfa2.lfUnderline);
203c2c66affSColin Finck expect(0, lfa2.lfStrikeOut);
204c2c66affSColin Finck ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
205c2c66affSColin Finck "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
206c2c66affSColin Finck expect(0, lfa2.lfOutPrecision);
207c2c66affSColin Finck expect(0, lfa2.lfClipPrecision);
208c2c66affSColin Finck expect(0, lfa2.lfQuality);
209c2c66affSColin Finck expect(0, lfa2.lfPitchAndFamily);
210c2c66affSColin Finck
211c2c66affSColin Finck GdipDeleteFont(font);
212c2c66affSColin Finck
213c2c66affSColin Finck memset(&lfa, 0, sizeof(LOGFONTA));
214c2c66affSColin Finck lfa.lfHeight = 25;
215c2c66affSColin Finck lfa.lfWidth = 25;
216c2c66affSColin Finck lfa.lfEscapement = lfa.lfOrientation = 50;
217c2c66affSColin Finck lfa.lfItalic = lfa.lfUnderline = lfa.lfStrikeOut = TRUE;
218c2c66affSColin Finck
219c2c66affSColin Finck memset(&lfa2, 0xff, sizeof(LOGFONTA));
220c2c66affSColin Finck lstrcpyA(lfa.lfFaceName, "Tahoma");
221c2c66affSColin Finck
222c2c66affSColin Finck stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
223c2c66affSColin Finck expect(Ok, stat);
224c2c66affSColin Finck stat = GdipGetLogFontA(font, graphics, &lfa2);
225c2c66affSColin Finck expect(Ok, stat);
226c2c66affSColin Finck
227c2c66affSColin Finck ok(lfa2.lfHeight < 0, "Expected negative height\n");
228c2c66affSColin Finck expect(0, lfa2.lfWidth);
229c2c66affSColin Finck expect(0, lfa2.lfEscapement);
230c2c66affSColin Finck expect(0, lfa2.lfOrientation);
231c2c66affSColin Finck ok((lfa2.lfWeight >= 100) && (lfa2.lfWeight <= 900), "Expected weight to be set\n");
232c2c66affSColin Finck expect(TRUE, lfa2.lfItalic);
233c2c66affSColin Finck expect(TRUE, lfa2.lfUnderline);
234c2c66affSColin Finck expect(TRUE, lfa2.lfStrikeOut);
235c2c66affSColin Finck ok(lfa2.lfCharSet == GetTextCharset(hdc) || lfa2.lfCharSet == ANSI_CHARSET,
236c2c66affSColin Finck "Expected %x or %x, got %x\n", GetTextCharset(hdc), ANSI_CHARSET, lfa2.lfCharSet);
237c2c66affSColin Finck expect(0, lfa2.lfOutPrecision);
238c2c66affSColin Finck expect(0, lfa2.lfClipPrecision);
239c2c66affSColin Finck expect(0, lfa2.lfQuality);
240c2c66affSColin Finck expect(0, lfa2.lfPitchAndFamily);
241c2c66affSColin Finck
242c2c66affSColin Finck stat = GdipGetFontStyle(font, &style);
243c2c66affSColin Finck expect(Ok, stat);
244c2c66affSColin Finck ok (style == (FontStyleItalic | FontStyleUnderline | FontStyleStrikeout),
245c2c66affSColin Finck "Expected , got %d\n", style);
246c2c66affSColin Finck
247c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
248c2c66affSColin Finck expect(Ok, stat);
249c2c66affSColin Finck expect(UnitWorld, unit);
250c2c66affSColin Finck
251c2c66affSColin Finck stat = GdipGetFontHeight(font, graphics, &rval);
252c2c66affSColin Finck expect(Ok, stat);
253c2c66affSColin Finck expectf(25.347656, rval);
254c2c66affSColin Finck stat = GdipGetFontSize(font, &rval);
255c2c66affSColin Finck expect(Ok, stat);
256c2c66affSColin Finck expectf(21.0, rval);
257c2c66affSColin Finck
258c2c66affSColin Finck stat = GdipGetFamily(font, &family);
259c2c66affSColin Finck expect(Ok, stat);
260c2c66affSColin Finck stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
261c2c66affSColin Finck expect(Ok, stat);
262c2c66affSColin Finck expect(2048, em_height);
263c2c66affSColin Finck stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
264c2c66affSColin Finck expect(Ok, stat);
265c2c66affSColin Finck expect(2472, line_spacing);
266c2c66affSColin Finck GdipDeleteFontFamily(family);
267c2c66affSColin Finck
268c2c66affSColin Finck GdipDeleteFont(font);
269c2c66affSColin Finck
270c2c66affSColin Finck memset(&lfa, 0, sizeof(lfa));
271c2c66affSColin Finck lfa.lfHeight = -25;
272c2c66affSColin Finck lstrcpyA(lfa.lfFaceName, "Tahoma");
273c2c66affSColin Finck stat = GdipCreateFontFromLogfontA(hdc, &lfa, &font);
274c2c66affSColin Finck expect(Ok, stat);
275c2c66affSColin Finck memset(&lfa2, 0xff, sizeof(lfa2));
276c2c66affSColin Finck stat = GdipGetLogFontA(font, graphics, &lfa2);
277c2c66affSColin Finck expect(Ok, stat);
278c2c66affSColin Finck expect(lfa.lfHeight, lfa2.lfHeight);
279c2c66affSColin Finck
280c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
281c2c66affSColin Finck expect(Ok, stat);
282c2c66affSColin Finck expect(UnitWorld, unit);
283c2c66affSColin Finck
284c2c66affSColin Finck stat = GdipGetFontHeight(font, graphics, &rval);
285c2c66affSColin Finck expect(Ok, stat);
286c2c66affSColin Finck expectf(30.175781, rval);
287c2c66affSColin Finck stat = GdipGetFontSize(font, &rval);
288c2c66affSColin Finck expect(Ok, stat);
289c2c66affSColin Finck expectf(25.0, rval);
290c2c66affSColin Finck
291c2c66affSColin Finck stat = GdipGetFamily(font, &family);
292c2c66affSColin Finck expect(Ok, stat);
293c2c66affSColin Finck stat = GdipGetEmHeight(family, FontStyleRegular, &em_height);
294c2c66affSColin Finck expect(Ok, stat);
295c2c66affSColin Finck expect(2048, em_height);
296c2c66affSColin Finck stat = GdipGetLineSpacing(family, FontStyleRegular, &line_spacing);
297c2c66affSColin Finck expect(Ok, stat);
298c2c66affSColin Finck expect(2472, line_spacing);
299c2c66affSColin Finck GdipDeleteFontFamily(family);
300c2c66affSColin Finck
301c2c66affSColin Finck GdipDeleteFont(font);
302c2c66affSColin Finck
303c2c66affSColin Finck GdipDeleteGraphics(graphics);
304c2c66affSColin Finck ReleaseDC(0, hdc);
305c2c66affSColin Finck }
306c2c66affSColin Finck
test_fontfamily(void)307c2c66affSColin Finck static void test_fontfamily (void)
308c2c66affSColin Finck {
309c2c66affSColin Finck GpFontFamily *family, *clonedFontFamily;
310c2c66affSColin Finck WCHAR itsName[LF_FACESIZE];
311c2c66affSColin Finck GpStatus stat;
312c2c66affSColin Finck
313c2c66affSColin Finck /* FontFamily cannot be NULL */
314c2c66affSColin Finck stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
315c2c66affSColin Finck expect (InvalidParameter, stat);
316c2c66affSColin Finck
317c2c66affSColin Finck /* FontFamily must be able to actually find the family.
318c2c66affSColin Finck * If it can't, any subsequent calls should fail.
319c2c66affSColin Finck */
320c2c66affSColin Finck stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
321c2c66affSColin Finck expect (FontFamilyNotFound, stat);
322c2c66affSColin Finck
323c2c66affSColin Finck /* Bitmap fonts are not found */
324c2c66affSColin Finck stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
325c2c66affSColin Finck expect (FontFamilyNotFound, stat);
326c2c66affSColin Finck if(stat == Ok) GdipDeleteFontFamily(family);
327c2c66affSColin Finck
328c2c66affSColin Finck stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
329c2c66affSColin Finck expect (Ok, stat);
330c2c66affSColin Finck
331c2c66affSColin Finck stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
332c2c66affSColin Finck expect (Ok, stat);
333c2c66affSColin Finck expect (0, lstrcmpiW(itsName, Tahoma));
334c2c66affSColin Finck
335c2c66affSColin Finck if (0)
336c2c66affSColin Finck {
337c2c66affSColin Finck /* Crashes on Windows XP SP2, Vista, and so Wine as well */
338c2c66affSColin Finck stat = GdipGetFamilyName (family, NULL, LANG_NEUTRAL);
339c2c66affSColin Finck expect (Ok, stat);
340c2c66affSColin Finck }
341c2c66affSColin Finck
342c2c66affSColin Finck /* Make sure we don't read old data */
343c2c66affSColin Finck ZeroMemory (itsName, sizeof(itsName));
344c2c66affSColin Finck stat = GdipCloneFontFamily(family, &clonedFontFamily);
345c2c66affSColin Finck expect (Ok, stat);
346c2c66affSColin Finck GdipDeleteFontFamily(family);
347c2c66affSColin Finck stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
348c2c66affSColin Finck expect(Ok, stat);
349c2c66affSColin Finck expect(0, lstrcmpiW(itsName, Tahoma));
350c2c66affSColin Finck
351c2c66affSColin Finck GdipDeleteFontFamily(clonedFontFamily);
352c2c66affSColin Finck }
353c2c66affSColin Finck
test_fontfamily_properties(void)354c2c66affSColin Finck static void test_fontfamily_properties (void)
355c2c66affSColin Finck {
356c2c66affSColin Finck GpFontFamily* FontFamily = NULL;
357c2c66affSColin Finck GpStatus stat;
358c2c66affSColin Finck UINT16 result = 0;
359c2c66affSColin Finck
360c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
361c2c66affSColin Finck expect(Ok, stat);
362c2c66affSColin Finck
363c2c66affSColin Finck stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
364c2c66affSColin Finck expect(Ok, stat);
365c2c66affSColin Finck ok (result == 2472, "Expected 2472, got %d\n", result);
366c2c66affSColin Finck result = 0;
367c2c66affSColin Finck stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
368c2c66affSColin Finck expect(Ok, stat);
369c2c66affSColin Finck ok(result == 2048, "Expected 2048, got %d\n", result);
370c2c66affSColin Finck result = 0;
371c2c66affSColin Finck stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
372c2c66affSColin Finck expect(Ok, stat);
373c2c66affSColin Finck ok(result == 2049, "Expected 2049, got %d\n", result);
374c2c66affSColin Finck result = 0;
375c2c66affSColin Finck stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
376c2c66affSColin Finck expect(Ok, stat);
377c2c66affSColin Finck ok(result == 423, "Expected 423, got %d\n", result);
378c2c66affSColin Finck GdipDeleteFontFamily(FontFamily);
379c2c66affSColin Finck
380c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
381c2c66affSColin Finck if(stat == FontFamilyNotFound)
382c2c66affSColin Finck skip("Times New Roman not installed\n");
383c2c66affSColin Finck else
384c2c66affSColin Finck {
385c2c66affSColin Finck result = 0;
386c2c66affSColin Finck stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
387c2c66affSColin Finck expect(Ok, stat);
388c2c66affSColin Finck ok(result == 2355, "Expected 2355, got %d\n", result);
389c2c66affSColin Finck result = 0;
390c2c66affSColin Finck stat = GdipGetEmHeight(FontFamily, FontStyleRegular, &result);
391c2c66affSColin Finck expect(Ok, stat);
392c2c66affSColin Finck ok(result == 2048, "Expected 2048, got %d\n", result);
393c2c66affSColin Finck result = 0;
394c2c66affSColin Finck stat = GdipGetCellAscent(FontFamily, FontStyleRegular, &result);
395c2c66affSColin Finck expect(Ok, stat);
396c2c66affSColin Finck ok(result == 1825, "Expected 1825, got %d\n", result);
397c2c66affSColin Finck result = 0;
398c2c66affSColin Finck stat = GdipGetCellDescent(FontFamily, FontStyleRegular, &result);
399c2c66affSColin Finck expect(Ok, stat);
400c2c66affSColin Finck ok(result == 443, "Expected 443 got %d\n", result);
401c2c66affSColin Finck GdipDeleteFontFamily(FontFamily);
402c2c66affSColin Finck }
403c2c66affSColin Finck }
404c2c66affSColin Finck
check_family(const char * context,GpFontFamily * family,WCHAR * name)405c2c66affSColin Finck static void check_family(const char* context, GpFontFamily *family, WCHAR *name)
406c2c66affSColin Finck {
407c2c66affSColin Finck GpStatus stat;
408c2c66affSColin Finck GpFont* font;
409c2c66affSColin Finck
410c2c66affSColin Finck *name = 0;
411c2c66affSColin Finck stat = GdipGetFamilyName(family, name, LANG_NEUTRAL);
412c2c66affSColin Finck ok(stat == Ok, "could not get the %s family name: %.8x\n", context, stat);
413c2c66affSColin Finck
414c2c66affSColin Finck stat = GdipCreateFont(family, 12, FontStyleRegular, UnitPixel, &font);
415c2c66affSColin Finck ok(stat == Ok, "could not create a font for the %s family: %.8x\n", context, stat);
416c2c66affSColin Finck if (stat == Ok)
417c2c66affSColin Finck {
418c2c66affSColin Finck stat = GdipDeleteFont(font);
419c2c66affSColin Finck ok(stat == Ok, "could not delete the %s family font: %.8x\n", context, stat);
420c2c66affSColin Finck }
421c2c66affSColin Finck
422c2c66affSColin Finck stat = GdipDeleteFontFamily(family);
423c2c66affSColin Finck ok(stat == Ok, "could not delete the %s family: %.8x\n", context, stat);
424c2c66affSColin Finck }
425c2c66affSColin Finck
test_getgenerics(void)426c2c66affSColin Finck static void test_getgenerics (void)
427c2c66affSColin Finck {
428c2c66affSColin Finck GpStatus stat;
429c2c66affSColin Finck GpFontFamily *family;
430c2c66affSColin Finck WCHAR sansname[LF_FACESIZE], serifname[LF_FACESIZE], mononame[LF_FACESIZE];
431c2c66affSColin Finck int missingfonts = 0;
432c2c66affSColin Finck
433c2c66affSColin Finck stat = GdipGetGenericFontFamilySansSerif(&family);
434c2c66affSColin Finck expect (Ok, stat);
435c2c66affSColin Finck if (stat == FontFamilyNotFound)
436c2c66affSColin Finck missingfonts = 1;
437c2c66affSColin Finck else
438c2c66affSColin Finck check_family("Sans Serif", family, sansname);
439c2c66affSColin Finck
440c2c66affSColin Finck stat = GdipGetGenericFontFamilySerif(&family);
441c2c66affSColin Finck expect (Ok, stat);
442c2c66affSColin Finck if (stat == FontFamilyNotFound)
443c2c66affSColin Finck missingfonts = 1;
444c2c66affSColin Finck else
445c2c66affSColin Finck check_family("Serif", family, serifname);
446c2c66affSColin Finck
447c2c66affSColin Finck stat = GdipGetGenericFontFamilyMonospace(&family);
448c2c66affSColin Finck expect (Ok, stat);
449c2c66affSColin Finck if (stat == FontFamilyNotFound)
450c2c66affSColin Finck missingfonts = 1;
451c2c66affSColin Finck else
452c2c66affSColin Finck check_family("Monospace", family, mononame);
453c2c66affSColin Finck
454c2c66affSColin Finck if (missingfonts && strcmp(winetest_platform, "wine") == 0)
455c2c66affSColin Finck trace("You may need to install either the Microsoft Web Fonts or the Liberation Fonts\n");
456c2c66affSColin Finck
457c2c66affSColin Finck /* Check that the family names are all different */
458c2c66affSColin Finck ok(lstrcmpiW(sansname, serifname) != 0, "Sans Serif and Serif families should be different: %s\n", wine_dbgstr_w(sansname));
459c2c66affSColin Finck ok(lstrcmpiW(sansname, mononame) != 0, "Sans Serif and Monospace families should be different: %s\n", wine_dbgstr_w(sansname));
460c2c66affSColin Finck ok(lstrcmpiW(serifname, mononame) != 0, "Serif and Monospace families should be different: %s\n", wine_dbgstr_w(serifname));
461c2c66affSColin Finck }
462c2c66affSColin Finck
test_installedfonts(void)463c2c66affSColin Finck static void test_installedfonts (void)
464c2c66affSColin Finck {
465c2c66affSColin Finck GpStatus stat;
466c2c66affSColin Finck GpFontCollection* collection=NULL;
467c2c66affSColin Finck
468c2c66affSColin Finck stat = GdipNewInstalledFontCollection(NULL);
469c2c66affSColin Finck expect (InvalidParameter, stat);
470c2c66affSColin Finck
471c2c66affSColin Finck stat = GdipNewInstalledFontCollection(&collection);
472c2c66affSColin Finck expect (Ok, stat);
473c2c66affSColin Finck ok (collection != NULL, "got NULL font collection\n");
474c2c66affSColin Finck }
475c2c66affSColin Finck
test_heightgivendpi(void)476c2c66affSColin Finck static void test_heightgivendpi(void)
477c2c66affSColin Finck {
478c2c66affSColin Finck GpStatus stat;
479c2c66affSColin Finck GpFont* font = NULL;
480c2c66affSColin Finck GpFontFamily* fontfamily = NULL;
481c2c66affSColin Finck REAL height;
482c2c66affSColin Finck Unit unit;
483c2c66affSColin Finck
484c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
485c2c66affSColin Finck expect(Ok, stat);
486c2c66affSColin Finck
487c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
488c2c66affSColin Finck expect(Ok, stat);
489c2c66affSColin Finck
490c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(NULL, 96, &height);
491c2c66affSColin Finck expect(InvalidParameter, stat);
492c2c66affSColin Finck
493c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, NULL);
494c2c66affSColin Finck expect(InvalidParameter, stat);
495c2c66affSColin Finck
496c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
497c2c66affSColin Finck expect(Ok, stat);
498c2c66affSColin Finck expectf(36.210938, height);
499c2c66affSColin Finck GdipDeleteFont(font);
500c2c66affSColin Finck
501c2c66affSColin Finck height = 12345;
502c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font);
503c2c66affSColin Finck expect(Ok, stat);
504c2c66affSColin Finck
505c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
506c2c66affSColin Finck expect(Ok, stat);
507c2c66affSColin Finck expect(UnitWorld, unit);
508c2c66affSColin Finck
509c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
510c2c66affSColin Finck expect(Ok, stat);
511c2c66affSColin Finck expectf(36.210938, height);
512c2c66affSColin Finck GdipDeleteFont(font);
513c2c66affSColin Finck
514c2c66affSColin Finck height = 12345;
515c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font);
516c2c66affSColin Finck expect(Ok, stat);
517c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
518c2c66affSColin Finck expect(Ok, stat);
519c2c66affSColin Finck expectf(48.281250, height);
520c2c66affSColin Finck GdipDeleteFont(font);
521c2c66affSColin Finck
522c2c66affSColin Finck height = 12345;
523c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font);
524c2c66affSColin Finck expect(Ok, stat);
525c2c66affSColin Finck
526c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
527c2c66affSColin Finck expect(Ok, stat);
528c2c66affSColin Finck expect(UnitInch, unit);
529c2c66affSColin Finck
530c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
531c2c66affSColin Finck expect(Ok, stat);
532c2c66affSColin Finck expectf(3476.250000, height);
533c2c66affSColin Finck GdipDeleteFont(font);
534c2c66affSColin Finck
535c2c66affSColin Finck height = 12345;
536c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font);
537c2c66affSColin Finck expect(Ok, stat);
538c2c66affSColin Finck
539c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
540c2c66affSColin Finck expect(Ok, stat);
541c2c66affSColin Finck expect(UnitDocument, unit);
542c2c66affSColin Finck
543c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
544c2c66affSColin Finck expect(Ok, stat);
545c2c66affSColin Finck expectf(11.587500, height);
546c2c66affSColin Finck GdipDeleteFont(font);
547c2c66affSColin Finck
548c2c66affSColin Finck height = 12345;
549c2c66affSColin Finck stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font);
550c2c66affSColin Finck expect(Ok, stat);
551c2c66affSColin Finck
552c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
553c2c66affSColin Finck expect(Ok, stat);
554c2c66affSColin Finck expect(UnitMillimeter, unit);
555c2c66affSColin Finck
556c2c66affSColin Finck stat = GdipGetFontHeightGivenDPI(font, 96, &height);
557c2c66affSColin Finck expect(Ok, stat);
558c2c66affSColin Finck expectf(136.860245, height);
559c2c66affSColin Finck GdipDeleteFont(font);
560c2c66affSColin Finck
561c2c66affSColin Finck GdipDeleteFontFamily(fontfamily);
562c2c66affSColin Finck }
563c2c66affSColin Finck
font_enum_proc(const LOGFONTW * lfe,const TEXTMETRICW * ntme,DWORD type,LPARAM lparam)564c2c66affSColin Finck static int CALLBACK font_enum_proc(const LOGFONTW *lfe, const TEXTMETRICW *ntme,
565c2c66affSColin Finck DWORD type, LPARAM lparam)
566c2c66affSColin Finck {
567c2c66affSColin Finck NEWTEXTMETRICW *ntm = (NEWTEXTMETRICW *)lparam;
568c2c66affSColin Finck
569c2c66affSColin Finck if (type != TRUETYPE_FONTTYPE) return 1;
570c2c66affSColin Finck
571c2c66affSColin Finck *ntm = *(NEWTEXTMETRICW *)ntme;
572c2c66affSColin Finck return 0;
573c2c66affSColin Finck }
574c2c66affSColin Finck
575c2c66affSColin Finck struct font_metrics
576c2c66affSColin Finck {
577c2c66affSColin Finck UINT16 em_height, line_spacing, ascent, descent;
578c2c66affSColin Finck REAL font_height, font_size;
579c2c66affSColin Finck INT lfHeight;
580c2c66affSColin Finck };
581c2c66affSColin Finck
gdi_get_font_metrics(LOGFONTW * lf,struct font_metrics * fm)582c2c66affSColin Finck static void gdi_get_font_metrics(LOGFONTW *lf, struct font_metrics *fm)
583c2c66affSColin Finck {
584c2c66affSColin Finck HDC hdc;
585c2c66affSColin Finck HFONT hfont;
586c2c66affSColin Finck NEWTEXTMETRICW ntm;
587c2c66affSColin Finck OUTLINETEXTMETRICW otm;
588c2c66affSColin Finck int ret;
589c2c66affSColin Finck
590c2c66affSColin Finck hdc = CreateCompatibleDC(0);
591c2c66affSColin Finck
592c2c66affSColin Finck /* it's the only way to get extended NEWTEXTMETRIC fields */
593c2c66affSColin Finck ret = EnumFontFamiliesExW(hdc, lf, font_enum_proc, (LPARAM)&ntm, 0);
594c2c66affSColin Finck ok(!ret, "EnumFontFamiliesExW failed to find %s\n", wine_dbgstr_w(lf->lfFaceName));
595c2c66affSColin Finck
596c2c66affSColin Finck hfont = CreateFontIndirectW(lf);
597c2c66affSColin Finck SelectObject(hdc, hfont);
598c2c66affSColin Finck
599c2c66affSColin Finck otm.otmSize = sizeof(otm);
600c2c66affSColin Finck ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
601c2c66affSColin Finck ok(ret, "GetOutlineTextMetrics failed\n");
602c2c66affSColin Finck
603c2c66affSColin Finck DeleteDC(hdc);
604c2c66affSColin Finck DeleteObject(hfont);
605c2c66affSColin Finck
606c2c66affSColin Finck fm->lfHeight = -otm.otmTextMetrics.tmAscent;
607c2c66affSColin Finck fm->line_spacing = ntm.ntmCellHeight;
608c2c66affSColin Finck fm->font_size = (REAL)otm.otmTextMetrics.tmAscent;
609c2c66affSColin Finck fm->font_height = (REAL)fm->line_spacing * fm->font_size / (REAL)ntm.ntmSizeEM;
610c2c66affSColin Finck fm->em_height = ntm.ntmSizeEM;
611c2c66affSColin Finck fm->ascent = ntm.ntmSizeEM;
612c2c66affSColin Finck fm->descent = ntm.ntmCellHeight - ntm.ntmSizeEM;
613c2c66affSColin Finck }
614c2c66affSColin Finck
gdip_get_font_metrics(GpFont * font,struct font_metrics * fm)615c2c66affSColin Finck static void gdip_get_font_metrics(GpFont *font, struct font_metrics *fm)
616c2c66affSColin Finck {
617c2c66affSColin Finck INT style;
618c2c66affSColin Finck GpFontFamily *family;
619c2c66affSColin Finck GpStatus stat;
620c2c66affSColin Finck
621c2c66affSColin Finck stat = GdipGetFontStyle(font, &style);
622c2c66affSColin Finck expect(Ok, stat);
623c2c66affSColin Finck
624c2c66affSColin Finck stat = GdipGetFontHeight(NULL, NULL, &fm->font_height);
625c2c66affSColin Finck expect(InvalidParameter, stat);
626c2c66affSColin Finck
627c2c66affSColin Finck stat = GdipGetFontHeight(font, NULL, NULL);
628c2c66affSColin Finck expect(InvalidParameter, stat);
629c2c66affSColin Finck
630c2c66affSColin Finck stat = GdipGetFontHeight(font, NULL, &fm->font_height);
631c2c66affSColin Finck expect(Ok, stat);
632c2c66affSColin Finck stat = GdipGetFontSize(font, &fm->font_size);
633c2c66affSColin Finck expect(Ok, stat);
634c2c66affSColin Finck
635c2c66affSColin Finck fm->lfHeight = (INT)(fm->font_size * -1.0);
636c2c66affSColin Finck
637c2c66affSColin Finck stat = GdipGetFamily(font, &family);
638c2c66affSColin Finck expect(Ok, stat);
639c2c66affSColin Finck
640c2c66affSColin Finck stat = GdipGetEmHeight(family, style, &fm->em_height);
641c2c66affSColin Finck expect(Ok, stat);
642c2c66affSColin Finck stat = GdipGetLineSpacing(family, style, &fm->line_spacing);
643c2c66affSColin Finck expect(Ok, stat);
644c2c66affSColin Finck stat = GdipGetCellAscent(family, style, &fm->ascent);
645c2c66affSColin Finck expect(Ok, stat);
646c2c66affSColin Finck stat = GdipGetCellDescent(family, style, &fm->descent);
647c2c66affSColin Finck expect(Ok, stat);
648c2c66affSColin Finck
649c2c66affSColin Finck GdipDeleteFontFamily(family);
650c2c66affSColin Finck }
651c2c66affSColin Finck
cmp_font_metrics(struct font_metrics * fm1,struct font_metrics * fm2,int line)652c2c66affSColin Finck static void cmp_font_metrics(struct font_metrics *fm1, struct font_metrics *fm2, int line)
653c2c66affSColin Finck {
654c2c66affSColin Finck ok_(__FILE__, line)(fm1->lfHeight == fm2->lfHeight, "lfHeight %d != %d\n", fm1->lfHeight, fm2->lfHeight);
655c2c66affSColin Finck ok_(__FILE__, line)(fm1->em_height == fm2->em_height, "em_height %u != %u\n", fm1->em_height, fm2->em_height);
656c2c66affSColin Finck ok_(__FILE__, line)(fm1->line_spacing == fm2->line_spacing, "line_spacing %u != %u\n", fm1->line_spacing, fm2->line_spacing);
657c2c66affSColin Finck ok_(__FILE__, line)(abs(fm1->ascent - fm2->ascent) <= 1, "ascent %u != %u\n", fm1->ascent, fm2->ascent);
658c2c66affSColin Finck ok_(__FILE__, line)(abs(fm1->descent - fm2->descent) <= 1, "descent %u != %u\n", fm1->descent, fm2->descent);
659c2c66affSColin Finck ok(fm1->font_height > 0.0, "fm1->font_height should be positive, got %f\n", fm1->font_height);
660c2c66affSColin Finck ok(fm2->font_height > 0.0, "fm2->font_height should be positive, got %f\n", fm2->font_height);
661c2c66affSColin Finck ok_(__FILE__, line)(fm1->font_height == fm2->font_height, "font_height %f != %f\n", fm1->font_height, fm2->font_height);
662c2c66affSColin Finck ok(fm1->font_size > 0.0, "fm1->font_size should be positive, got %f\n", fm1->font_size);
663c2c66affSColin Finck ok(fm2->font_size > 0.0, "fm2->font_size should be positive, got %f\n", fm2->font_size);
664c2c66affSColin Finck ok_(__FILE__, line)(fm1->font_size == fm2->font_size, "font_size %f != %f\n", fm1->font_size, fm2->font_size);
665c2c66affSColin Finck }
666c2c66affSColin Finck
test_font_metrics(void)667c2c66affSColin Finck static void test_font_metrics(void)
668c2c66affSColin Finck {
669c2c66affSColin Finck LOGFONTW lf;
670c2c66affSColin Finck GpFont *font;
671c2c66affSColin Finck GpFontFamily *family;
672c2c66affSColin Finck GpGraphics *graphics;
673c2c66affSColin Finck GpStatus stat;
674c2c66affSColin Finck Unit unit;
675c2c66affSColin Finck struct font_metrics fm_gdi, fm_gdip;
676c2c66affSColin Finck HDC hdc;
677c2c66affSColin Finck
678c2c66affSColin Finck hdc = CreateCompatibleDC(0);
679c2c66affSColin Finck stat = GdipCreateFromHDC(hdc, &graphics);
680c2c66affSColin Finck expect(Ok, stat);
681c2c66affSColin Finck
682c2c66affSColin Finck memset(&lf, 0, sizeof(lf));
683c2c66affSColin Finck
684c2c66affSColin Finck /* Tahoma,-13 */
685c2c66affSColin Finck lstrcpyW(lf.lfFaceName, Tahoma);
686c2c66affSColin Finck lf.lfHeight = -13;
687c2c66affSColin Finck stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
688c2c66affSColin Finck expect(Ok, stat);
689c2c66affSColin Finck
690c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
691c2c66affSColin Finck expect(Ok, stat);
692c2c66affSColin Finck expect(UnitWorld, unit);
693c2c66affSColin Finck
694c2c66affSColin Finck gdip_get_font_metrics(font, &fm_gdip);
695c2c66affSColin Finck trace("gdiplus:\n");
696c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
697c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
698c2c66affSColin Finck fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
699c2c66affSColin Finck fm_gdip.font_height, fm_gdip.font_size);
700c2c66affSColin Finck
701c2c66affSColin Finck gdi_get_font_metrics(&lf, &fm_gdi);
702c2c66affSColin Finck trace("gdi:\n");
703c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
704c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
705c2c66affSColin Finck fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
706c2c66affSColin Finck fm_gdi.font_height, fm_gdi.font_size);
707c2c66affSColin Finck
708c2c66affSColin Finck cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
709c2c66affSColin Finck
710c2c66affSColin Finck stat = GdipGetLogFontW(font, graphics, &lf);
711c2c66affSColin Finck expect(Ok, stat);
712c2c66affSColin Finck ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
713c2c66affSColin Finck gdi_get_font_metrics(&lf, &fm_gdi);
714c2c66affSColin Finck trace("gdi:\n");
715c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
716c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
717c2c66affSColin Finck fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
718c2c66affSColin Finck fm_gdi.font_height, fm_gdi.font_size);
719c2c66affSColin Finck ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
720c2c66affSColin Finck
721c2c66affSColin Finck cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
722c2c66affSColin Finck
723c2c66affSColin Finck GdipDeleteFont(font);
724c2c66affSColin Finck
725c2c66affSColin Finck /* Tahoma,13 */
726c2c66affSColin Finck lstrcpyW(lf.lfFaceName, Tahoma);
727c2c66affSColin Finck lf.lfHeight = 13;
728c2c66affSColin Finck stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
729c2c66affSColin Finck expect(Ok, stat);
730c2c66affSColin Finck
731c2c66affSColin Finck stat = GdipGetFontUnit(font, &unit);
732c2c66affSColin Finck expect(Ok, stat);
733c2c66affSColin Finck expect(UnitWorld, unit);
734c2c66affSColin Finck
735c2c66affSColin Finck gdip_get_font_metrics(font, &fm_gdip);
736c2c66affSColin Finck trace("gdiplus:\n");
737c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
738c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
739c2c66affSColin Finck fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
740c2c66affSColin Finck fm_gdip.font_height, fm_gdip.font_size);
741c2c66affSColin Finck
742c2c66affSColin Finck gdi_get_font_metrics(&lf, &fm_gdi);
743c2c66affSColin Finck trace("gdi:\n");
744c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
745c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
746c2c66affSColin Finck fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
747c2c66affSColin Finck fm_gdi.font_height, fm_gdi.font_size);
748c2c66affSColin Finck
749c2c66affSColin Finck cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
750c2c66affSColin Finck
751c2c66affSColin Finck stat = GdipGetLogFontW(font, graphics, &lf);
752c2c66affSColin Finck expect(Ok, stat);
753c2c66affSColin Finck ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
754c2c66affSColin Finck gdi_get_font_metrics(&lf, &fm_gdi);
755c2c66affSColin Finck trace("gdi:\n");
756c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
757c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
758c2c66affSColin Finck fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
759c2c66affSColin Finck fm_gdi.font_height, fm_gdi.font_size);
760c2c66affSColin Finck ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
761c2c66affSColin Finck
762c2c66affSColin Finck cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
763c2c66affSColin Finck
764c2c66affSColin Finck GdipDeleteFont(font);
765c2c66affSColin Finck
766c2c66affSColin Finck stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
767c2c66affSColin Finck expect(Ok, stat);
768c2c66affSColin Finck
769c2c66affSColin Finck /* Tahoma,13 */
770c2c66affSColin Finck stat = GdipCreateFont(family, 13.0, FontStyleRegular, UnitPixel, &font);
771c2c66affSColin Finck expect(Ok, stat);
772c2c66affSColin Finck
773c2c66affSColin Finck gdip_get_font_metrics(font, &fm_gdip);
774c2c66affSColin Finck trace("gdiplus:\n");
775c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
776c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
777c2c66affSColin Finck fm_gdip.em_height, fm_gdip.line_spacing, fm_gdip.ascent, fm_gdip.descent,
778c2c66affSColin Finck fm_gdip.font_height, fm_gdip.font_size);
779c2c66affSColin Finck
780c2c66affSColin Finck stat = GdipGetLogFontW(font, graphics, &lf);
781c2c66affSColin Finck expect(Ok, stat);
782c2c66affSColin Finck ok(lf.lfHeight < 0, "lf.lfHeight should be negative, got %d\n", lf.lfHeight);
783c2c66affSColin Finck gdi_get_font_metrics(&lf, &fm_gdi);
784c2c66affSColin Finck trace("gdi:\n");
785c2c66affSColin Finck trace("%s,%d: EmHeight %u, LineSpacing %u, CellAscent %u, CellDescent %u, FontHeight %f, FontSize %f\n",
786c2c66affSColin Finck wine_dbgstr_w(lf.lfFaceName), lf.lfHeight,
787c2c66affSColin Finck fm_gdi.em_height, fm_gdi.line_spacing, fm_gdi.ascent, fm_gdi.descent,
788c2c66affSColin Finck fm_gdi.font_height, fm_gdi.font_size);
789c2c66affSColin Finck ok((REAL)lf.lfHeight * -1.0 == fm_gdi.font_size, "expected %f, got %f\n", (REAL)lf.lfHeight * -1.0, fm_gdi.font_size);
790c2c66affSColin Finck
791c2c66affSColin Finck cmp_font_metrics(&fm_gdip, &fm_gdi, __LINE__);
792c2c66affSColin Finck
793c2c66affSColin Finck stat = GdipGetLogFontW(font, NULL, &lf);
794c2c66affSColin Finck expect(InvalidParameter, stat);
795c2c66affSColin Finck
796c2c66affSColin Finck GdipDeleteFont(font);
797c2c66affSColin Finck
798c2c66affSColin Finck stat = GdipCreateFont(family, -13.0, FontStyleRegular, UnitPixel, &font);
799c2c66affSColin Finck expect(InvalidParameter, stat);
800c2c66affSColin Finck
801c2c66affSColin Finck GdipDeleteFontFamily(family);
802c2c66affSColin Finck
803c2c66affSColin Finck GdipDeleteGraphics(graphics);
804c2c66affSColin Finck DeleteDC(hdc);
805c2c66affSColin Finck }
806c2c66affSColin Finck
test_font_substitution(void)807c2c66affSColin Finck static void test_font_substitution(void)
808c2c66affSColin Finck {
809c2c66affSColin Finck WCHAR ms_shell_dlg[LF_FACESIZE];
810c2c66affSColin Finck char fallback_font[LF_FACESIZE];
811c2c66affSColin Finck HDC hdc;
812c2c66affSColin Finck HFONT hfont;
813c2c66affSColin Finck LOGFONTA lf;
814c2c66affSColin Finck GpStatus status;
815c2c66affSColin Finck GpGraphics *graphics;
816c2c66affSColin Finck GpFont *font;
817c2c66affSColin Finck GpFontFamily *family;
818c2c66affSColin Finck int ret;
819c2c66affSColin Finck
820c2c66affSColin Finck hdc = CreateCompatibleDC(0);
821c2c66affSColin Finck status = GdipCreateFromHDC(hdc, &graphics);
822c2c66affSColin Finck expect(Ok, status);
823c2c66affSColin Finck
824c2c66affSColin Finck hfont = GetStockObject(DEFAULT_GUI_FONT);
825c2c66affSColin Finck ok(hfont != 0, "GetStockObject(DEFAULT_GUI_FONT) failed\n");
826c2c66affSColin Finck
827c2c66affSColin Finck memset(&lf, 0xfe, sizeof(lf));
828c2c66affSColin Finck ret = GetObjectA(hfont, sizeof(lf), &lf);
829c2c66affSColin Finck ok(ret == sizeof(lf), "GetObject failed\n");
830c2c66affSColin Finck ok(!lstrcmpA(lf.lfFaceName, "MS Shell Dlg"), "wrong face name %s\n", lf.lfFaceName);
831c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, lf.lfFaceName, -1, ms_shell_dlg, LF_FACESIZE);
832c2c66affSColin Finck
833c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
834c2c66affSColin Finck expect(Ok, status);
835c2c66affSColin Finck memset(&lf, 0xfe, sizeof(lf));
836c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
837c2c66affSColin Finck expect(Ok, status);
838c2c66affSColin Finck ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") ||
839c2c66affSColin Finck !lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
840c2c66affSColin Finck GdipDeleteFont(font);
841c2c66affSColin Finck
842c2c66affSColin Finck status = GdipCreateFontFamilyFromName(ms_shell_dlg, NULL, &family);
843c2c66affSColin Finck expect(Ok, status);
844c2c66affSColin Finck status = GdipCreateFont(family, 12, FontStyleRegular, UnitPoint, &font);
845c2c66affSColin Finck expect(Ok, status);
846c2c66affSColin Finck memset(&lf, 0xfe, sizeof(lf));
847c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
848c2c66affSColin Finck expect(Ok, status);
849c2c66affSColin Finck ok(!lstrcmpA(lf.lfFaceName, "Microsoft Sans Serif") ||
850c2c66affSColin Finck !lstrcmpA(lf.lfFaceName, "Tahoma"), "wrong face name %s\n", lf.lfFaceName);
851c2c66affSColin Finck GdipDeleteFont(font);
852c2c66affSColin Finck GdipDeleteFontFamily(family);
853c2c66affSColin Finck
854c2c66affSColin Finck status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family);
855c2c66affSColin Finck ok(status == FontFamilyNotFound, "expected FontFamilyNotFound, got %d\n", status);
856c2c66affSColin Finck
857c2c66affSColin Finck /* nonexistent fonts fallback to Arial, or something else if it's missing */
858c2c66affSColin Finck strcpy(lf.lfFaceName,"Arial");
859c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
860c2c66affSColin Finck expect(Ok, status);
861c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
862c2c66affSColin Finck expect(Ok, status);
863c2c66affSColin Finck strcpy(fallback_font,lf.lfFaceName);
864c2c66affSColin Finck trace("fallback font %s\n", fallback_font);
865c2c66affSColin Finck GdipDeleteFont(font);
866c2c66affSColin Finck
867c2c66affSColin Finck lstrcpyA(lf.lfFaceName, "ThisFontShouldNotExist");
868c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
869c2c66affSColin Finck expect(Ok, status);
870c2c66affSColin Finck memset(&lf, 0xfe, sizeof(lf));
871c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
872c2c66affSColin Finck expect(Ok, status);
873c2c66affSColin Finck ok(!lstrcmpA(lf.lfFaceName, fallback_font), "wrong face name %s / %s\n", lf.lfFaceName, fallback_font);
874c2c66affSColin Finck GdipDeleteFont(font);
875c2c66affSColin Finck
876c2c66affSColin Finck /* empty FaceName */
877c2c66affSColin Finck lf.lfFaceName[0] = 0;
878c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
879c2c66affSColin Finck expect(Ok, status);
880c2c66affSColin Finck memset(&lf, 0xfe, sizeof(lf));
881c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
882c2c66affSColin Finck expect(Ok, status);
883c2c66affSColin Finck ok(!lstrcmpA(lf.lfFaceName, fallback_font), "wrong face name %s / %s\n", lf.lfFaceName, fallback_font);
884c2c66affSColin Finck GdipDeleteFont(font);
885c2c66affSColin Finck
886c2c66affSColin Finck /* zeroing out lfWeight and lfCharSet leads to font creation failure */
887c2c66affSColin Finck lf.lfWeight = 0;
888c2c66affSColin Finck lf.lfCharSet = 0;
889c2c66affSColin Finck lstrcpyA(lf.lfFaceName, "ThisFontShouldNotExist");
890c2c66affSColin Finck font = NULL;
891c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
892c2c66affSColin Finck todo_wine
893c2c66affSColin Finck ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
894c2c66affSColin Finck "expected NotTrueTypeFont, got %d\n", status);
895c2c66affSColin Finck /* FIXME: remove when wine is fixed */
896c2c66affSColin Finck if (font) GdipDeleteFont(font);
897c2c66affSColin Finck
898c2c66affSColin Finck /* empty FaceName */
899c2c66affSColin Finck lf.lfFaceName[0] = 0;
900c2c66affSColin Finck font = NULL;
901c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
902c2c66affSColin Finck todo_wine
903c2c66affSColin Finck ok(status == NotTrueTypeFont || broken(status == FileNotFound), /* before XP */
904c2c66affSColin Finck "expected NotTrueTypeFont, got %d\n", status);
905c2c66affSColin Finck /* FIXME: remove when wine is fixed */
906c2c66affSColin Finck if (font) GdipDeleteFont(font);
907c2c66affSColin Finck
908c2c66affSColin Finck GdipDeleteGraphics(graphics);
909c2c66affSColin Finck DeleteDC(hdc);
910c2c66affSColin Finck }
911c2c66affSColin Finck
test_font_transform(void)912c2c66affSColin Finck static void test_font_transform(void)
913c2c66affSColin Finck {
914c2c66affSColin Finck static const WCHAR string[] = { 'A',0 };
915c2c66affSColin Finck GpStatus status;
916c2c66affSColin Finck HDC hdc;
917c2c66affSColin Finck LOGFONTA lf;
918c2c66affSColin Finck GpFont *font;
919c2c66affSColin Finck GpGraphics *graphics;
920c2c66affSColin Finck GpMatrix *matrix;
921c2c66affSColin Finck GpStringFormat *format, *typographic;
922c2c66affSColin Finck PointF pos[1] = { { 0,0 } };
923c2c66affSColin Finck REAL height, margin_y;
924c2c66affSColin Finck RectF bounds, rect;
925c2c66affSColin Finck
926c2c66affSColin Finck hdc = CreateCompatibleDC(0);
927c2c66affSColin Finck status = GdipCreateFromHDC(hdc, &graphics);
928c2c66affSColin Finck expect(Ok, status);
929c2c66affSColin Finck
930c2c66affSColin Finck status = GdipSetPageUnit(graphics, UnitPixel);
931c2c66affSColin Finck expect(Ok, status);
932c2c66affSColin Finck
933c2c66affSColin Finck status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
934c2c66affSColin Finck expect(Ok, status);
935c2c66affSColin Finck status = GdipStringFormatGetGenericTypographic(&typographic);
936c2c66affSColin Finck expect(Ok, status);
937c2c66affSColin Finck
938c2c66affSColin Finck memset(&lf, 0, sizeof(lf));
939c2c66affSColin Finck lstrcpyA(lf.lfFaceName, "Tahoma");
940c2c66affSColin Finck lf.lfHeight = -100;
941c2c66affSColin Finck lf.lfWidth = 100;
942c2c66affSColin Finck status = GdipCreateFontFromLogfontA(hdc, &lf, &font);
943c2c66affSColin Finck expect(Ok, status);
944c2c66affSColin Finck
945c2c66affSColin Finck margin_y = 100.0 / 8.0;
946c2c66affSColin Finck
947c2c66affSColin Finck /* identity matrix */
948c2c66affSColin Finck status = GdipCreateMatrix(&matrix);
949c2c66affSColin Finck expect(Ok, status);
950c2c66affSColin Finck status = GdipSetWorldTransform(graphics, matrix);
951c2c66affSColin Finck expect(Ok, status);
952c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
953c2c66affSColin Finck expect(Ok, status);
954c2c66affSColin Finck expect(-100, lf.lfHeight);
955c2c66affSColin Finck expect(0, lf.lfWidth);
956c2c66affSColin Finck expect(0, lf.lfEscapement);
957c2c66affSColin Finck expect(0, lf.lfOrientation);
958c2c66affSColin Finck status = GdipGetFontHeight(font, graphics, &height);
959c2c66affSColin Finck expect(Ok, status);
960c2c66affSColin Finck expectf(120.703125, height);
961c2c66affSColin Finck set_rect_empty(&rect);
962c2c66affSColin Finck set_rect_empty(&bounds);
963c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
964c2c66affSColin Finck expect(Ok, status);
965c2c66affSColin Finck expectf(0.0, bounds.X);
966c2c66affSColin Finck expectf(0.0, bounds.Y);
967c2c66affSColin Finck todo_wine
968c2c66affSColin Finck expectf(height + margin_y, bounds.Height);
969c2c66affSColin Finck set_rect_empty(&rect);
970c2c66affSColin Finck set_rect_empty(&bounds);
971c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
972c2c66affSColin Finck expect(Ok, status);
973c2c66affSColin Finck expectf(0.0, bounds.X);
974c2c66affSColin Finck expectf(0.0, bounds.Y);
975c2c66affSColin Finck expectf_(height, bounds.Height, 1.0);
976c2c66affSColin Finck set_rect_empty(&bounds);
977c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
978c2c66affSColin Finck DriverStringOptionsCmapLookup, NULL, &bounds);
979c2c66affSColin Finck expect(Ok, status);
980c2c66affSColin Finck expectf(0.0, bounds.X);
981c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.05);
982c2c66affSColin Finck expectf_(height, bounds.Height, 0.5);
983c2c66affSColin Finck set_rect_empty(&bounds);
984c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
985c2c66affSColin Finck DriverStringOptionsCmapLookup, matrix, &bounds);
986c2c66affSColin Finck expect(Ok, status);
987c2c66affSColin Finck expectf(0.0, bounds.X);
988c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.05);
989c2c66affSColin Finck expectf_(height, bounds.Height, 0.5);
990c2c66affSColin Finck
991c2c66affSColin Finck /* scale matrix */
992c2c66affSColin Finck status = GdipScaleMatrix(matrix, 2.0, 3.0, MatrixOrderAppend);
993c2c66affSColin Finck expect(Ok, status);
994c2c66affSColin Finck status = GdipSetWorldTransform(graphics, matrix);
995c2c66affSColin Finck expect(Ok, status);
996c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
997c2c66affSColin Finck expect(Ok, status);
998c2c66affSColin Finck expect(-300, lf.lfHeight);
999c2c66affSColin Finck expect(0, lf.lfWidth);
1000c2c66affSColin Finck expect(0, lf.lfEscapement);
1001c2c66affSColin Finck expect(0, lf.lfOrientation);
1002c2c66affSColin Finck status = GdipGetFontHeight(font, graphics, &height);
1003c2c66affSColin Finck expect(Ok, status);
1004c2c66affSColin Finck expectf(120.703125, height);
1005c2c66affSColin Finck set_rect_empty(&rect);
1006c2c66affSColin Finck set_rect_empty(&bounds);
1007c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1008c2c66affSColin Finck expect(Ok, status);
1009c2c66affSColin Finck expectf(0.0, bounds.X);
1010c2c66affSColin Finck expectf(0.0, bounds.Y);
1011c2c66affSColin Finck todo_wine
1012c2c66affSColin Finck expectf(height + margin_y, bounds.Height);
1013c2c66affSColin Finck set_rect_empty(&rect);
1014c2c66affSColin Finck set_rect_empty(&bounds);
1015c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1016c2c66affSColin Finck expect(Ok, status);
1017c2c66affSColin Finck expectf(0.0, bounds.X);
1018c2c66affSColin Finck expectf(0.0, bounds.Y);
1019c2c66affSColin Finck expectf_(height, bounds.Height, 0.05);
1020c2c66affSColin Finck set_rect_empty(&bounds);
1021c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1022c2c66affSColin Finck DriverStringOptionsCmapLookup, NULL, &bounds);
1023c2c66affSColin Finck expect(Ok, status);
1024c2c66affSColin Finck expectf(0.0, bounds.X);
1025c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.05);
1026c2c66affSColin Finck expectf_(height, bounds.Height, 0.2);
1027c2c66affSColin Finck set_rect_empty(&bounds);
1028c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1029c2c66affSColin Finck DriverStringOptionsCmapLookup, matrix, &bounds);
1030c2c66affSColin Finck expect(Ok, status);
1031c2c66affSColin Finck expectf(0.0, bounds.X);
1032c2c66affSColin Finck todo_wine
1033c2c66affSColin Finck expectf_(-300.0, bounds.Y, 0.15);
1034c2c66affSColin Finck todo_wine
1035c2c66affSColin Finck expectf(height * 3.0, bounds.Height);
1036c2c66affSColin Finck
1037c2c66affSColin Finck /* scale + ratate matrix */
1038c2c66affSColin Finck status = GdipRotateMatrix(matrix, 45.0, MatrixOrderAppend);
1039c2c66affSColin Finck expect(Ok, status);
1040c2c66affSColin Finck status = GdipSetWorldTransform(graphics, matrix);
1041c2c66affSColin Finck expect(Ok, status);
1042c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
1043c2c66affSColin Finck expect(Ok, status);
1044c2c66affSColin Finck expect(-300, lf.lfHeight);
1045c2c66affSColin Finck expect(0, lf.lfWidth);
1046c2c66affSColin Finck expect_(3151, lf.lfEscapement, 1);
1047c2c66affSColin Finck expect_(3151, lf.lfOrientation, 1);
1048c2c66affSColin Finck status = GdipGetFontHeight(font, graphics, &height);
1049c2c66affSColin Finck expect(Ok, status);
1050c2c66affSColin Finck expectf(120.703125, height);
1051c2c66affSColin Finck set_rect_empty(&rect);
1052c2c66affSColin Finck set_rect_empty(&bounds);
1053c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1054c2c66affSColin Finck expect(Ok, status);
1055c2c66affSColin Finck expectf(0.0, bounds.X);
1056c2c66affSColin Finck expectf(0.0, bounds.Y);
1057c2c66affSColin Finck todo_wine
1058c2c66affSColin Finck expectf(height + margin_y, bounds.Height);
1059c2c66affSColin Finck set_rect_empty(&rect);
1060c2c66affSColin Finck set_rect_empty(&bounds);
1061c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1062c2c66affSColin Finck expect(Ok, status);
1063c2c66affSColin Finck expectf(0.0, bounds.X);
1064c2c66affSColin Finck expectf(0.0, bounds.Y);
1065c2c66affSColin Finck expectf_(height, bounds.Height, 0.05);
1066c2c66affSColin Finck set_rect_empty(&bounds);
1067c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1068c2c66affSColin Finck DriverStringOptionsCmapLookup, NULL, &bounds);
1069c2c66affSColin Finck expect(Ok, status);
1070c2c66affSColin Finck expectf(0.0, bounds.X);
1071c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.05);
1072c2c66affSColin Finck expectf_(height, bounds.Height, 0.2);
1073c2c66affSColin Finck set_rect_empty(&bounds);
1074c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1075c2c66affSColin Finck DriverStringOptionsCmapLookup, matrix, &bounds);
1076c2c66affSColin Finck expect(Ok, status);
1077c2c66affSColin Finck todo_wine
1078c2c66affSColin Finck expectf_(-43.814377, bounds.X, 0.05);
1079c2c66affSColin Finck todo_wine
1080c2c66affSColin Finck expectf_(-212.235611, bounds.Y, 0.05);
1081c2c66affSColin Finck todo_wine
1082c2c66affSColin Finck expectf_(340.847534, bounds.Height, 0.05);
1083c2c66affSColin Finck
1084c2c66affSColin Finck /* scale + ratate + shear matrix */
1085c2c66affSColin Finck status = GdipShearMatrix(matrix, 4.0, 5.0, MatrixOrderAppend);
1086c2c66affSColin Finck expect(Ok, status);
1087c2c66affSColin Finck status = GdipSetWorldTransform(graphics, matrix);
1088c2c66affSColin Finck expect(Ok, status);
1089c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
1090c2c66affSColin Finck expect(Ok, status);
1091c2c66affSColin Finck todo_wine
1092c2c66affSColin Finck expect(1032, lf.lfHeight);
1093c2c66affSColin Finck expect(0, lf.lfWidth);
1094c2c66affSColin Finck expect_(3099, lf.lfEscapement, 1);
1095c2c66affSColin Finck expect_(3099, lf.lfOrientation, 1);
1096c2c66affSColin Finck status = GdipGetFontHeight(font, graphics, &height);
1097c2c66affSColin Finck expect(Ok, status);
1098c2c66affSColin Finck expectf(120.703125, height);
1099c2c66affSColin Finck set_rect_empty(&rect);
1100c2c66affSColin Finck set_rect_empty(&bounds);
1101c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1102c2c66affSColin Finck expect(Ok, status);
1103c2c66affSColin Finck expectf(0.0, bounds.X);
1104c2c66affSColin Finck expectf(0.0, bounds.Y);
1105c2c66affSColin Finck todo_wine
1106c2c66affSColin Finck expectf(height + margin_y, bounds.Height);
1107c2c66affSColin Finck set_rect_empty(&rect);
1108c2c66affSColin Finck set_rect_empty(&bounds);
1109c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1110c2c66affSColin Finck expect(Ok, status);
1111c2c66affSColin Finck expectf(0.0, bounds.X);
1112c2c66affSColin Finck expectf(0.0, bounds.Y);
1113c2c66affSColin Finck expectf_(height, bounds.Height, 0.2);
1114c2c66affSColin Finck set_rect_empty(&bounds);
1115c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1116c2c66affSColin Finck DriverStringOptionsCmapLookup, NULL, &bounds);
1117c2c66affSColin Finck expect(Ok, status);
1118c2c66affSColin Finck expectf(0.0, bounds.X);
1119c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.2);
1120c2c66affSColin Finck expectf_(height, bounds.Height, 0.2);
1121c2c66affSColin Finck set_rect_empty(&bounds);
1122c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1123c2c66affSColin Finck DriverStringOptionsCmapLookup, matrix, &bounds);
1124c2c66affSColin Finck expect(Ok, status);
1125c2c66affSColin Finck todo_wine
1126c2c66affSColin Finck expectf_(-636.706848, bounds.X, 0.05);
1127c2c66affSColin Finck todo_wine
1128c2c66affSColin Finck expectf_(-175.257523, bounds.Y, 0.05);
1129c2c66affSColin Finck todo_wine
1130c2c66affSColin Finck expectf_(1532.984985, bounds.Height, 0.05);
1131c2c66affSColin Finck
1132c2c66affSColin Finck /* scale + ratate + shear + translate matrix */
1133c2c66affSColin Finck status = GdipTranslateMatrix(matrix, 10.0, 20.0, MatrixOrderAppend);
1134c2c66affSColin Finck expect(Ok, status);
1135c2c66affSColin Finck status = GdipSetWorldTransform(graphics, matrix);
1136c2c66affSColin Finck expect(Ok, status);
1137c2c66affSColin Finck status = GdipGetLogFontA(font, graphics, &lf);
1138c2c66affSColin Finck expect(Ok, status);
1139c2c66affSColin Finck todo_wine
1140c2c66affSColin Finck expect(1032, lf.lfHeight);
1141c2c66affSColin Finck expect(0, lf.lfWidth);
1142c2c66affSColin Finck expect_(3099, lf.lfEscapement, 1);
1143c2c66affSColin Finck expect_(3099, lf.lfOrientation, 1);
1144c2c66affSColin Finck status = GdipGetFontHeight(font, graphics, &height);
1145c2c66affSColin Finck expect(Ok, status);
1146c2c66affSColin Finck expectf(120.703125, height);
1147c2c66affSColin Finck set_rect_empty(&rect);
1148c2c66affSColin Finck set_rect_empty(&bounds);
1149c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
1150c2c66affSColin Finck expect(Ok, status);
1151c2c66affSColin Finck expectf(0.0, bounds.X);
1152c2c66affSColin Finck expectf(0.0, bounds.Y);
1153c2c66affSColin Finck todo_wine
1154c2c66affSColin Finck expectf(height + margin_y, bounds.Height);
1155c2c66affSColin Finck set_rect_empty(&rect);
1156c2c66affSColin Finck set_rect_empty(&bounds);
1157c2c66affSColin Finck status = GdipMeasureString(graphics, string, -1, font, &rect, typographic, &bounds, NULL, NULL);
1158c2c66affSColin Finck expect(Ok, status);
1159c2c66affSColin Finck expectf(0.0, bounds.X);
1160c2c66affSColin Finck expectf(0.0, bounds.Y);
1161c2c66affSColin Finck expectf_(height, bounds.Height, 0.1);
1162c2c66affSColin Finck set_rect_empty(&bounds);
1163c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1164c2c66affSColin Finck DriverStringOptionsCmapLookup, NULL, &bounds);
1165c2c66affSColin Finck expect(Ok, status);
1166c2c66affSColin Finck expectf(0.0, bounds.X);
1167c2c66affSColin Finck expectf_(-100.0, bounds.Y, 0.2);
1168c2c66affSColin Finck expectf_(height, bounds.Height, 0.2);
1169c2c66affSColin Finck set_rect_empty(&bounds);
1170c2c66affSColin Finck status = GdipMeasureDriverString(graphics, (const UINT16 *)string, -1, font, pos,
1171c2c66affSColin Finck DriverStringOptionsCmapLookup, matrix, &bounds);
1172c2c66affSColin Finck expect(Ok, status);
1173c2c66affSColin Finck todo_wine
1174c2c66affSColin Finck expectf_(-626.706848, bounds.X, 0.05);
1175c2c66affSColin Finck todo_wine
1176c2c66affSColin Finck expectf_(-155.257523, bounds.Y, 0.05);
1177c2c66affSColin Finck todo_wine
1178c2c66affSColin Finck expectf_(1532.984985, bounds.Height, 0.05);
1179c2c66affSColin Finck
1180c2c66affSColin Finck GdipDeleteMatrix(matrix);
1181c2c66affSColin Finck GdipDeleteFont(font);
1182c2c66affSColin Finck GdipDeleteGraphics(graphics);
1183c2c66affSColin Finck GdipDeleteStringFormat(typographic);
1184c2c66affSColin Finck GdipDeleteStringFormat(format);
1185c2c66affSColin Finck DeleteDC(hdc);
1186c2c66affSColin Finck }
1187c2c66affSColin Finck
test_GdipGetFontCollectionFamilyList(void)118870c9f307SAmine Khaldi static void test_GdipGetFontCollectionFamilyList(void)
118970c9f307SAmine Khaldi {
119070c9f307SAmine Khaldi GpFontFamily *family, *family2;
119170c9f307SAmine Khaldi GpFontCollection *collection;
119270c9f307SAmine Khaldi INT found, count;
119370c9f307SAmine Khaldi GpStatus status;
119470c9f307SAmine Khaldi
119570c9f307SAmine Khaldi status = GdipNewInstalledFontCollection(&collection);
119670c9f307SAmine Khaldi ok(status == Ok, "Failed to get system collection, status %d.\n", status);
119770c9f307SAmine Khaldi
119870c9f307SAmine Khaldi count = 0;
119970c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyCount(collection, &count);
120070c9f307SAmine Khaldi ok(status == Ok, "Failed to get family count, status %d.\n", status);
120170c9f307SAmine Khaldi ok(count > 0, "Unexpected empty collection.\n");
120270c9f307SAmine Khaldi
120370c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(NULL, 0, NULL, NULL);
120470c9f307SAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
120570c9f307SAmine Khaldi
120670c9f307SAmine Khaldi found = 123;
120770c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(NULL, 0, NULL, &found);
120870c9f307SAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
120970c9f307SAmine Khaldi ok(found == 123, "Unexpected list count %d.\n", found);
121070c9f307SAmine Khaldi
121170c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(collection, 0, NULL, NULL);
121270c9f307SAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
121370c9f307SAmine Khaldi
121470c9f307SAmine Khaldi found = 123;
121570c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(collection, 0, NULL, &found);
121670c9f307SAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
121770c9f307SAmine Khaldi ok(found == 123, "Unexpected list count %d.\n", found);
121870c9f307SAmine Khaldi
121970c9f307SAmine Khaldi found = 123;
122070c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(collection, 1, NULL, &found);
122170c9f307SAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
122270c9f307SAmine Khaldi ok(found == 123, "Unexpected list count %d.\n", found);
122370c9f307SAmine Khaldi
122470c9f307SAmine Khaldi family = NULL;
122570c9f307SAmine Khaldi found = 0;
122670c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(collection, 1, &family, &found);
122770c9f307SAmine Khaldi ok(status == Ok, "Failed to get family list, status %d.\n", status);
122870c9f307SAmine Khaldi ok(found == 1, "Unexpected list count %d.\n", found);
122970c9f307SAmine Khaldi ok(family != NULL, "Expected family instance.\n");
123070c9f307SAmine Khaldi
123170c9f307SAmine Khaldi family = NULL;
123270c9f307SAmine Khaldi found = 0;
123370c9f307SAmine Khaldi status = GdipGetFontCollectionFamilyList(collection, 1, &family2, &found);
123470c9f307SAmine Khaldi ok(status == Ok, "Failed to get family list, status %d.\n", status);
123570c9f307SAmine Khaldi ok(found == 1, "Unexpected list count %d.\n", found);
123670c9f307SAmine Khaldi ok(family2 != family, "Unexpected family instance.\n");
123770c9f307SAmine Khaldi
123870c9f307SAmine Khaldi GdipDeleteFontFamily(family);
123970c9f307SAmine Khaldi GdipDeleteFontFamily(family2);
124070c9f307SAmine Khaldi }
124170c9f307SAmine Khaldi
test_GdipGetFontCollectionFamilyCount(void)1242*7d57324dSAmine Khaldi static void test_GdipGetFontCollectionFamilyCount(void)
1243*7d57324dSAmine Khaldi {
1244*7d57324dSAmine Khaldi GpFontCollection *collection;
1245*7d57324dSAmine Khaldi GpStatus status;
1246*7d57324dSAmine Khaldi INT count;
1247*7d57324dSAmine Khaldi
1248*7d57324dSAmine Khaldi status = GdipGetFontCollectionFamilyCount(NULL, NULL);
1249*7d57324dSAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
1250*7d57324dSAmine Khaldi
1251*7d57324dSAmine Khaldi count = 123;
1252*7d57324dSAmine Khaldi status = GdipGetFontCollectionFamilyCount(NULL, &count);
1253*7d57324dSAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
1254*7d57324dSAmine Khaldi ok(count == 123, "Unexpected family count %d.\n", count);
1255*7d57324dSAmine Khaldi
1256*7d57324dSAmine Khaldi status = GdipNewInstalledFontCollection(&collection);
1257*7d57324dSAmine Khaldi ok(status == Ok, "Failed to get system collection, status %d.\n", status);
1258*7d57324dSAmine Khaldi
1259*7d57324dSAmine Khaldi status = GdipGetFontCollectionFamilyCount(collection, NULL);
1260*7d57324dSAmine Khaldi ok(status == InvalidParameter, "Unexpected status %d.\n", status);
1261*7d57324dSAmine Khaldi }
1262*7d57324dSAmine Khaldi
START_TEST(font)1263c2c66affSColin Finck START_TEST(font)
1264c2c66affSColin Finck {
1265c2c66affSColin Finck struct GdiplusStartupInput gdiplusStartupInput;
1266c2c66affSColin Finck ULONG_PTR gdiplusToken;
1267c2c66affSColin Finck HMODULE hmsvcrt;
1268c2c66affSColin Finck int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
1269c2c66affSColin Finck
1270c2c66affSColin Finck /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1271c2c66affSColin Finck hmsvcrt = LoadLibraryA("msvcrt");
1272c2c66affSColin Finck _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
1273c2c66affSColin Finck if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
1274c2c66affSColin Finck
1275c2c66affSColin Finck gdiplusStartupInput.GdiplusVersion = 1;
1276c2c66affSColin Finck gdiplusStartupInput.DebugEventCallback = NULL;
1277c2c66affSColin Finck gdiplusStartupInput.SuppressBackgroundThread = 0;
1278c2c66affSColin Finck gdiplusStartupInput.SuppressExternalCodecs = 0;
1279c2c66affSColin Finck
1280c2c66affSColin Finck GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1281c2c66affSColin Finck
128270c9f307SAmine Khaldi test_long_name();
1283c2c66affSColin Finck test_font_transform();
1284c2c66affSColin Finck test_font_substitution();
1285c2c66affSColin Finck test_font_metrics();
1286c2c66affSColin Finck test_createfont();
1287c2c66affSColin Finck test_logfont();
1288c2c66affSColin Finck test_fontfamily();
1289c2c66affSColin Finck test_fontfamily_properties();
1290c2c66affSColin Finck test_getgenerics();
1291c2c66affSColin Finck test_installedfonts();
1292c2c66affSColin Finck test_heightgivendpi();
129370c9f307SAmine Khaldi test_GdipGetFontCollectionFamilyList();
1294*7d57324dSAmine Khaldi test_GdipGetFontCollectionFamilyCount();
1295c2c66affSColin Finck
1296c2c66affSColin Finck GdiplusShutdown(gdiplusToken);
1297c2c66affSColin Finck }
1298