1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for CreateFontIndirect
5  * PROGRAMMERS:     Timo Kreuzer
6  *                  Katayama Hirofumi MZ
7  */
8 
9 #include "precomp.h"
10 
11 #define trace_if(val, msg) do { if (!(val)) trace(msg); } while (0)
12 
13 void
14 Test_CreateFontIndirectA(void)
15 {
16     LOGFONTA logfont;
17     HFONT hFont;
18     ULONG ret;
19     ENUMLOGFONTEXDVW elfedv2;
20 
21     logfont.lfHeight = 12;
22     logfont.lfWidth = 0;
23     logfont.lfEscapement = 0;
24     logfont.lfOrientation = 0;
25     logfont.lfWeight = FW_NORMAL;
26     logfont.lfItalic = 0;
27     logfont.lfUnderline = 0;
28     logfont.lfStrikeOut = 0;
29     logfont.lfCharSet = DEFAULT_CHARSET;
30     logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
31     logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
32     logfont.lfQuality = PROOF_QUALITY;
33     logfont.lfPitchAndFamily = DEFAULT_PITCH;
34     memset(logfont.lfFaceName, 'A', LF_FACESIZE);
35     hFont = CreateFontIndirectA(&logfont);
36     ok(hFont != 0, "CreateFontIndirectA failed\n");
37 
38     memset(&elfedv2, 0, sizeof(elfedv2));
39     ret = GetObjectW(hFont, sizeof(elfedv2), &elfedv2);
40     ok(ret == sizeof(ENUMLOGFONTEXW) + 2*sizeof(DWORD), "ret = %ld\n", ret);
41     ok(elfedv2.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == 0, "\n");
42     ok(elfedv2.elfEnumLogfontEx.elfFullName[0] == 0, "\n");
43 }
44 
45 void
46 Test_CreateFontIndirectW(void)
47 {
48     LOGFONTW logfont;
49     HFONT hFont;
50     ULONG ret;
51     ENUMLOGFONTEXDVW elfedv2;
52 
53     logfont.lfHeight = 12;
54     logfont.lfWidth = 0;
55     logfont.lfEscapement = 0;
56     logfont.lfOrientation = 0;
57     logfont.lfWeight = FW_NORMAL;
58     logfont.lfItalic = 0;
59     logfont.lfUnderline = 0;
60     logfont.lfStrikeOut = 0;
61     logfont.lfCharSet = DEFAULT_CHARSET;
62     logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
63     logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
64     logfont.lfQuality = PROOF_QUALITY;
65     logfont.lfPitchAndFamily = DEFAULT_PITCH;
66     memset(logfont.lfFaceName, 'A', LF_FACESIZE * 2);
67     hFont = CreateFontIndirectW(&logfont);
68     ok(hFont != 0, "CreateFontIndirectW failed\n");
69 
70     memset(&elfedv2, 0, sizeof(elfedv2));
71     ret = GetObjectW(hFont, sizeof(elfedv2), &elfedv2);
72     ok(ret == sizeof(ENUMLOGFONTEXW) + 2*sizeof(DWORD), "\n");
73     ok(elfedv2.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == ((WCHAR)'A' << 8) + 'A', "\n");
74     ok(elfedv2.elfEnumLogfontEx.elfFullName[0] == 0, "\n");
75     /* Theres a bunch of data in elfFullName ... */
76 }
77 
78 void
79 Test_CreateFontIndirectExA(void)
80 {
81     ENUMLOGFONTEXDVA elfedva, elfedva2;
82     ENUMLOGFONTEXDVW elfedvw;
83     ENUMLOGFONTEXA *penumlfa;
84     LOGFONTA *plogfonta;
85     HFONT hFont;
86     ULONG ret;
87 
88     memset(&elfedva, 0, sizeof(elfedva));
89     penumlfa = &elfedva.elfEnumLogfontEx;
90     plogfonta = &elfedva.elfEnumLogfontEx.elfLogFont;
91 
92     plogfonta->lfHeight = 12;
93     plogfonta->lfWidth = 0;
94     plogfonta->lfEscapement = 0;
95     plogfonta->lfOrientation = 0;
96     plogfonta->lfWeight = FW_NORMAL;
97     plogfonta->lfItalic = 0;
98     plogfonta->lfUnderline = 0;
99     plogfonta->lfStrikeOut = 0;
100     plogfonta->lfCharSet = DEFAULT_CHARSET;
101     plogfonta->lfOutPrecision = OUT_DEFAULT_PRECIS;
102     plogfonta->lfClipPrecision = CLIP_DEFAULT_PRECIS;
103     plogfonta->lfQuality = PROOF_QUALITY;
104     plogfonta->lfPitchAndFamily = DEFAULT_PITCH;
105 
106     memset(plogfonta->lfFaceName, 'A', LF_FACESIZE * sizeof(WCHAR));
107     memset(penumlfa->elfFullName, 'B', LF_FULLFACESIZE * sizeof(WCHAR));
108 
109     hFont = CreateFontIndirectExA(&elfedva);
110     ok(hFont != 0, "CreateFontIndirectExA failed\n");
111 
112     ret = GetObjectW(hFont, sizeof(elfedvw), &elfedvw);
113     ok(ret == sizeof(ENUMLOGFONTEXW) + 2*sizeof(DWORD), "\n");
114     ok(elfedvw.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == 0, "\n");
115     ok(elfedvw.elfEnumLogfontEx.elfFullName[LF_FULLFACESIZE-1] == 0, "\n");
116 
117     memset(&elfedva2, 0, sizeof(elfedva2));
118     ret = GetObjectA(hFont, sizeof(elfedva2), &elfedva2);
119     ok(ret == sizeof(ENUMLOGFONTEXDVA), "ret = %ld\n", ret);
120     ok(elfedva2.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == 0, "\n");
121     ok(elfedva2.elfEnumLogfontEx.elfFullName[LF_FULLFACESIZE-1] == 0, "\n");
122 }
123 
124 void
125 Test_CreateFontIndirectExW(void)
126 {
127     ENUMLOGFONTEXDVW elfedv, elfedv2;
128     ENUMLOGFONTEXDVA elfedva;
129     ENUMLOGFONTEXW *penumlfw;
130     LOGFONTW *plogfontw;
131     HFONT hFont;
132     ULONG ret;
133 
134     memset(&elfedv, 0, sizeof(elfedv));
135     penumlfw = &elfedv.elfEnumLogfontEx;
136     plogfontw = &elfedv.elfEnumLogfontEx.elfLogFont;
137 
138     plogfontw->lfHeight = 12;
139     plogfontw->lfWidth = 0;
140     plogfontw->lfEscapement = 0;
141     plogfontw->lfOrientation = 0;
142     plogfontw->lfWeight = FW_NORMAL;
143     plogfontw->lfItalic = 0;
144     plogfontw->lfUnderline = 0;
145     plogfontw->lfStrikeOut = 0;
146     plogfontw->lfCharSet = DEFAULT_CHARSET;
147     plogfontw->lfOutPrecision = OUT_DEFAULT_PRECIS;
148     plogfontw->lfClipPrecision = CLIP_DEFAULT_PRECIS;
149     plogfontw->lfQuality = PROOF_QUALITY;
150     plogfontw->lfPitchAndFamily = DEFAULT_PITCH;
151 
152     memset(plogfontw->lfFaceName, 'A', LF_FACESIZE * sizeof(WCHAR));
153     memset(penumlfw->elfFullName, 'B', LF_FULLFACESIZE * sizeof(WCHAR));
154 
155     hFont = CreateFontIndirectExW(&elfedv);
156     ok(hFont != 0, "CreateFontIndirectExW failed\n");
157 
158     memset(&elfedv2, 0, sizeof(elfedv2));
159     ret = GetObjectW(hFont, sizeof(elfedv2), &elfedv2);
160     ok(ret == sizeof(ENUMLOGFONTEXW) + 2*sizeof(DWORD), "\n");
161     ok(elfedv2.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == ((WCHAR)'A' << 8) + 'A', "\n");
162     ok(elfedv2.elfEnumLogfontEx.elfFullName[LF_FULLFACESIZE-1] == ((WCHAR)'B' << 8) + 'B', "\n");
163 
164     memset(&elfedva, 0, sizeof(elfedva));
165     ret = GetObjectA(hFont, sizeof(elfedva), &elfedva);
166     ok(ret == sizeof(ENUMLOGFONTEXDVA), "\n");
167     ok(elfedva.elfEnumLogfontEx.elfLogFont.lfFaceName[LF_FACESIZE-1] == '?', "\n");
168     ok(elfedva.elfEnumLogfontEx.elfFullName[LF_FULLFACESIZE-1] == 0, "\n");
169 }
170 
171 static INT CALLBACK
172 is_truetype_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm,
173                       DWORD type, LPARAM lParam)
174 {
175     if (type != TRUETYPE_FONTTYPE) return 1;
176 
177     return 0;
178 }
179 
180 static BOOL is_truetype_font_installed(HDC hDC, const char *name)
181 {
182     LOGFONT lf;
183     ZeroMemory(&lf, sizeof(lf));
184     lf.lfCharSet = DEFAULT_CHARSET;
185     lstrcpy(lf.lfFaceName, name);
186     if (!EnumFontFamiliesExA(hDC, &lf, is_truetype_font_proc, 0, 0))
187         return TRUE;
188     return FALSE;
189 }
190 
191 static INT CALLBACK
192 is_charset_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm,
193                                DWORD type, LPARAM lParam)
194 {
195     if (ntm->tmCharSet == (BYTE)lParam)
196         return 0;
197     return 1;
198 }
199 
200 static BOOL is_charset_font_installed(HDC hDC, BYTE CharSet)
201 {
202     LOGFONT lf;
203     ZeroMemory(&lf, sizeof(lf));
204     lf.lfCharSet = DEFAULT_CHARSET;
205     if (!EnumFontFamiliesExA(hDC, &lf, is_charset_font_proc, CharSet, 0))
206         return TRUE;
207     return FALSE;
208 }
209 
210 /* TMPF_FIXED_PITCH is confusing. brain-damaged api */
211 #define _TMPF_VAR_PITCH     TMPF_FIXED_PITCH
212 
213 static INT CALLBACK
214 is_fixed_charset_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm,
215                                      DWORD type, LPARAM lParam)
216 {
217     if (ntm->tmCharSet == (BYTE)lParam && !(ntm->tmPitchAndFamily & _TMPF_VAR_PITCH))
218         return 0;
219     return 1;
220 }
221 
222 static BOOL
223 is_fixed_charset_font_installed(HDC hDC, BYTE CharSet)
224 {
225     LOGFONT lf;
226     ZeroMemory(&lf, sizeof(lf));
227     lf.lfCharSet = DEFAULT_CHARSET;
228     if (!EnumFontFamiliesExA(hDC, &lf, is_fixed_charset_font_proc, CharSet, 0))
229         return TRUE;
230     return FALSE;
231 }
232 
233 static void
234 Test_FontPresence(void)
235 {
236     HDC hDC;
237 
238     hDC = CreateCompatibleDC(NULL);
239 
240     ok(is_truetype_font_installed(hDC, "Arial"), "'Arial' is not found\n");
241     ok(is_truetype_font_installed(hDC, "Courier New"), "'Courier New' is not found\n");
242     ok(is_truetype_font_installed(hDC, "Marlett"), "'Marlett' is not found\n");
243     ok(is_truetype_font_installed(hDC, "MS Shell Dlg"), "'MS Shell Dlg' is not found\n");
244     ok(is_truetype_font_installed(hDC, "Tahoma"), "'Tahoma' is not found\n");
245     ok(is_truetype_font_installed(hDC, "Times New Roman"), "'Times New Roman' is not found\n");
246 
247     ok(is_charset_font_installed(hDC, ANSI_CHARSET), "ANSI_CHARSET fonts are not found\n");
248     ok(is_charset_font_installed(hDC, SYMBOL_CHARSET), "SYMBOL_CHARSET fonts are not found\n");
249     trace_if(is_charset_font_installed(hDC, SHIFTJIS_CHARSET), "SHIFTJIS_CHARSET fonts are not found\n");
250     trace_if(is_charset_font_installed(hDC, HANGUL_CHARSET), "HANGUL_CHARSET fonts are not found\n");
251     trace_if(is_charset_font_installed(hDC, GB2312_CHARSET), "GB2312_CHARSET fonts are not found\n");
252     trace_if(is_charset_font_installed(hDC, CHINESEBIG5_CHARSET), "CHINESEBIG5_CHARSET fonts are not found\n");
253     ok(is_charset_font_installed(hDC, OEM_CHARSET), "OEM_CHARSET fonts are not found\n");
254     trace_if(is_charset_font_installed(hDC, JOHAB_CHARSET), "JOHAB_CHARSET fonts are not found\n");
255     trace_if(is_charset_font_installed(hDC, HEBREW_CHARSET), "HEBREW_CHARSET fonts are not found\n");
256     trace_if(is_charset_font_installed(hDC, ARABIC_CHARSET), "ARABIC_CHARSET fonts are not found\n");
257     trace_if(is_charset_font_installed(hDC, GREEK_CHARSET), "GREEK_CHARSET fonts are not found\n");
258     trace_if(is_charset_font_installed(hDC, TURKISH_CHARSET), "TURKISH_CHARSET fonts are not found\n");
259     trace_if(is_charset_font_installed(hDC, VIETNAMESE_CHARSET), "VIETNAMESE_CHARSET fonts are not found\n");
260     trace_if(is_charset_font_installed(hDC, THAI_CHARSET), "THAI_CHARSET fonts are not found\n");
261     trace_if(is_charset_font_installed(hDC, EASTEUROPE_CHARSET), "EASTEUROPE_CHARSET fonts are not found\n");
262     trace_if(is_charset_font_installed(hDC, RUSSIAN_CHARSET), "RUSSIAN_CHARSET fonts are not found\n");
263     trace_if(is_charset_font_installed(hDC, MAC_CHARSET), "MAC_CHARSET fonts are not found\n");
264     trace_if(is_charset_font_installed(hDC, BALTIC_CHARSET), "BALTIC_CHARSET fonts are not found\n");
265 
266     ok(is_fixed_charset_font_installed(hDC, ANSI_CHARSET), "fixed ANSI_CHARSET fonts are not found\n");
267     trace_if(is_fixed_charset_font_installed(hDC, SHIFTJIS_CHARSET), "fixed SHIFTJIS_CHARSET fonts are not found\n");
268     trace_if(is_fixed_charset_font_installed(hDC, HANGUL_CHARSET), "fixed HANGUL_CHARSET fonts are not found\n");
269     trace_if(is_fixed_charset_font_installed(hDC, GB2312_CHARSET), "fixed GB2312_CHARSET fonts are not found\n");
270     trace_if(is_fixed_charset_font_installed(hDC, CHINESEBIG5_CHARSET), "fixed CHINESEBIG5_CHARSET fonts are not found\n");
271     ok(is_fixed_charset_font_installed(hDC, OEM_CHARSET), "fixed OEM_CHARSET fonts are not found\n");
272     trace_if(is_fixed_charset_font_installed(hDC, JOHAB_CHARSET), "fixed JOHAB_CHARSET fonts are not found\n");
273     trace_if(is_fixed_charset_font_installed(hDC, HEBREW_CHARSET), "fixed HEBREW_CHARSET fonts are not found\n");
274     trace_if(is_fixed_charset_font_installed(hDC, ARABIC_CHARSET), "fixed ARABIC_CHARSET fonts are not found\n");
275     trace_if(is_fixed_charset_font_installed(hDC, GREEK_CHARSET), "fixed GREEK_CHARSET fonts are not found\n");
276     trace_if(is_fixed_charset_font_installed(hDC, TURKISH_CHARSET), "fixed TURKISH_CHARSET fonts are not found\n");
277     trace_if(is_fixed_charset_font_installed(hDC, VIETNAMESE_CHARSET), "fixed VIETNAMESE_CHARSET fonts are not found\n");
278     trace_if(is_fixed_charset_font_installed(hDC, THAI_CHARSET), "fixed THAI_CHARSET fonts are not found\n");
279     trace_if(is_fixed_charset_font_installed(hDC, EASTEUROPE_CHARSET), "fixed EASTEUROPE_CHARSET fonts are not found\n");
280     trace_if(is_fixed_charset_font_installed(hDC, RUSSIAN_CHARSET), "fixed RUSSIAN_CHARSET fonts are not found\n");
281     trace_if(is_fixed_charset_font_installed(hDC, MAC_CHARSET), "fixed MAC_CHARSET fonts are not found\n");
282     trace_if(is_fixed_charset_font_installed(hDC, BALTIC_CHARSET), "fixed BALTIC_CHARSET fonts are not found\n");
283 
284     DeleteDC(hDC);
285 }
286 
287 /* NOTE: TMPF_FIXED_PITCH is confusing and brain-dead. */
288 #define _TMPF_VAR_PITCH TMPF_FIXED_PITCH
289 
290 typedef enum TRISTATE {
291     TS_UNKNOWN,
292     TS_TRUE,
293     TS_FALSE
294 } TRISTATE;
295 
296 typedef struct FONT_SEL_TEST {
297     CHAR        FaceNameBefore[LF_FACESIZE];
298 
299     BYTE        CharSetBefore;
300     BYTE        CharSetAfter;
301 
302     TRISTATE    BoldBefore;
303     TRISTATE    BoldAfter;
304 
305     BYTE        ItalicBefore;
306     TRISTATE    ItalicAfter;
307 
308     BYTE        UnderlineBefore;
309     TRISTATE    UnderlineAfter;
310 
311     BYTE        StruckOutBefore;
312     TRISTATE    StruckOutAfter;
313 
314     TRISTATE    FixedPitchBefore;
315     TRISTATE    FixedPitchAfter;
316 } FONT_SEL_TEST;
317 
318 static FONT_SEL_TEST g_Entries[] =
319 {
320     /* Entry #0: default */
321     {
322         "",
323         DEFAULT_CHARSET, DEFAULT_CHARSET,
324         TS_UNKNOWN, TS_FALSE,
325         TS_UNKNOWN, TS_FALSE,
326         TS_UNKNOWN, TS_FALSE,
327         TS_UNKNOWN, TS_FALSE,
328         TS_UNKNOWN, TS_FALSE
329     },
330     /* Entry #1: symbol font*/
331     {
332         "",
333         SYMBOL_CHARSET, SYMBOL_CHARSET
334     },
335     /* Entry #2: non-bold */
336     {
337         "",
338         DEFAULT_CHARSET, DEFAULT_CHARSET,
339         TS_FALSE, TS_FALSE
340     },
341     /* Entry #3: bold */
342     {
343         "",
344         DEFAULT_CHARSET, DEFAULT_CHARSET,
345         TS_TRUE, TS_TRUE
346     },
347     /* Entry #4: non-italic (without specifying bold) */
348     {
349         "",
350         DEFAULT_CHARSET, DEFAULT_CHARSET,
351         TS_UNKNOWN, TS_FALSE,
352         FALSE, TS_FALSE
353     },
354     /* Entry #5: italic (without specifying bold) */
355     {
356         "",
357         DEFAULT_CHARSET, DEFAULT_CHARSET,
358         TS_UNKNOWN, TS_FALSE,
359         TRUE, TS_TRUE
360     },
361     /* Entry #6: non-underline (without specifying bold) */
362     {
363         "",
364         DEFAULT_CHARSET, DEFAULT_CHARSET,
365         TS_UNKNOWN, TS_FALSE,
366         FALSE, TS_UNKNOWN,
367         FALSE, TS_FALSE
368     },
369     /* Entry #7: underline (without specifying bold) */
370     {
371         "",
372         DEFAULT_CHARSET, DEFAULT_CHARSET,
373         TS_UNKNOWN, TS_FALSE,
374         FALSE, TS_UNKNOWN,
375         TRUE, TS_TRUE
376     },
377     /* Entry #8: struck-out (without specifying bold) */
378     {
379         "",
380         DEFAULT_CHARSET, DEFAULT_CHARSET,
381         TS_UNKNOWN, TS_FALSE,
382         FALSE, TS_UNKNOWN,
383         FALSE, TS_UNKNOWN,
384         TRUE, TS_TRUE
385     },
386     /* Entry #9: non-struck-out (without specifying bold) */
387     {
388         "",
389         DEFAULT_CHARSET, DEFAULT_CHARSET,
390         TS_UNKNOWN, TS_FALSE,
391         FALSE, TS_UNKNOWN,
392         FALSE, TS_UNKNOWN,
393         FALSE, TS_FALSE
394     },
395     /* Entry #10: fixed-pitch (without specifying bold) */
396     {
397         "",
398         DEFAULT_CHARSET, DEFAULT_CHARSET,
399         TS_UNKNOWN, TS_FALSE,
400         FALSE, TS_UNKNOWN,
401         FALSE, TS_UNKNOWN,
402         FALSE, TS_UNKNOWN,
403         TS_TRUE, TS_TRUE
404     },
405     /* Entry #11: non-fixed-pitch (without specifying bold) */
406     {
407         "",
408         DEFAULT_CHARSET, DEFAULT_CHARSET,
409         TS_UNKNOWN, TS_FALSE,
410         FALSE, TS_UNKNOWN,
411         FALSE, TS_UNKNOWN,
412         FALSE, TS_UNKNOWN,
413         TS_FALSE, TS_FALSE
414     },
415     /* Entry #12: fixed-pitch and bold */
416     {
417         "",
418         DEFAULT_CHARSET, DEFAULT_CHARSET,
419         TS_TRUE, TS_TRUE,
420         FALSE, TS_UNKNOWN,
421         FALSE, TS_UNKNOWN,
422         FALSE, TS_UNKNOWN,
423         TS_TRUE, TS_TRUE
424     },
425     /* Entry #13: non-fixed-pitch and bold */
426     {
427         "",
428         DEFAULT_CHARSET, DEFAULT_CHARSET,
429         TS_TRUE, TS_TRUE,
430         FALSE, TS_UNKNOWN,
431         FALSE, TS_UNKNOWN,
432         FALSE, TS_UNKNOWN,
433         TS_FALSE, TS_FALSE
434     },
435     /* Entry #14: OEM_CHARSET */
436     {
437         "",
438         OEM_CHARSET, OEM_CHARSET,
439         TS_UNKNOWN, TS_FALSE
440     },
441     /* Entry #15: OEM_CHARSET and bold */
442     {
443         "",
444         OEM_CHARSET, OEM_CHARSET,
445         TS_TRUE, TS_TRUE
446     },
447     /* Entry #16: OEM_CHARSET and fixed-pitch */
448     {
449         "",
450         OEM_CHARSET, OEM_CHARSET,
451         TS_UNKNOWN, TS_FALSE,
452         FALSE, TS_UNKNOWN,
453         FALSE, TS_UNKNOWN,
454         FALSE, TS_UNKNOWN,
455         TS_TRUE, TS_TRUE
456     },
457     /* Entry #17: CHINESEBIG5_CHARSET (Chinese) */
458     {
459         "",
460         CHINESEBIG5_CHARSET, CHINESEBIG5_CHARSET,
461         TS_UNKNOWN, TS_FALSE
462     },
463     /* Entry #18: CHINESEBIG5_CHARSET and bold */
464     {
465         "",
466         CHINESEBIG5_CHARSET, CHINESEBIG5_CHARSET,
467         TS_TRUE, TS_TRUE
468     },
469     /* Entry #19: CHINESEBIG5_CHARSET and fixed-pitch */
470     {
471         "",
472         CHINESEBIG5_CHARSET, CHINESEBIG5_CHARSET,
473         TS_UNKNOWN, TS_FALSE,
474         FALSE, TS_UNKNOWN,
475         FALSE, TS_UNKNOWN,
476         FALSE, TS_UNKNOWN,
477         TS_TRUE, TS_TRUE
478     },
479     /* Entry #20: GB2312_CHARSET (Chinese) */
480     {
481         "",
482         GB2312_CHARSET, GB2312_CHARSET,
483         TS_UNKNOWN, TS_FALSE
484     },
485     /* Entry #21: GB2312_CHARSET and bold */
486     {
487         "",
488         GB2312_CHARSET, GB2312_CHARSET,
489         TS_TRUE, TS_TRUE
490     },
491     /* Entry #22: GB2312_CHARSET and fixed-pitch */
492     {
493         "",
494         GB2312_CHARSET, GB2312_CHARSET,
495         TS_UNKNOWN, TS_FALSE,
496         FALSE, TS_UNKNOWN,
497         FALSE, TS_UNKNOWN,
498         FALSE, TS_UNKNOWN,
499         TS_TRUE, TS_TRUE
500     },
501     /* Entry #23: RUSSIAN_CHARSET (Russian) */
502     {
503         "",
504         RUSSIAN_CHARSET, RUSSIAN_CHARSET,
505         TS_UNKNOWN, TS_FALSE
506     },
507     /* Entry #24: RUSSIAN_CHARSET and bold */
508     {
509         "",
510         RUSSIAN_CHARSET, RUSSIAN_CHARSET,
511         TS_TRUE, TS_TRUE
512     },
513     /* Entry #25: RUSSIAN_CHARSET and italic */
514     {
515         "",
516         RUSSIAN_CHARSET, RUSSIAN_CHARSET,
517         TS_UNKNOWN, TS_FALSE,
518         TRUE, TS_TRUE,
519     },
520     /* Entry #26: RUSSIAN_CHARSET and fixed-pitch */
521     {
522         "",
523         RUSSIAN_CHARSET, RUSSIAN_CHARSET,
524         TS_UNKNOWN, TS_FALSE,
525         FALSE, TS_UNKNOWN,
526         FALSE, TS_UNKNOWN,
527         FALSE, TS_UNKNOWN,
528         TS_TRUE, TS_TRUE
529     },
530     /* Entry #27: SHIFTJIS_CHARSET (Japanese) */
531     {
532         "",
533         SHIFTJIS_CHARSET, SHIFTJIS_CHARSET,
534         TS_UNKNOWN, TS_FALSE
535     },
536     /* Entry #28: SHIFTJIS_CHARSET and bold */
537     {
538         "",
539         SHIFTJIS_CHARSET, SHIFTJIS_CHARSET,
540         TS_TRUE, TS_TRUE
541     },
542     /* Entry #29: SHIFTJIS_CHARSET and fixed-pitch */
543     {
544         "",
545         SHIFTJIS_CHARSET, SHIFTJIS_CHARSET,
546         TS_UNKNOWN, TS_FALSE,
547         FALSE, TS_UNKNOWN,
548         FALSE, TS_UNKNOWN,
549         FALSE, TS_UNKNOWN,
550         TS_TRUE, TS_TRUE
551     },
552     /* Entry #30: HANGUL_CHARSET (Korean) */
553     {
554         "",
555         HANGUL_CHARSET, HANGUL_CHARSET,
556         TS_UNKNOWN, TS_FALSE
557     },
558     /* Entry #31: HANGUL_CHARSET and bold */
559     {
560         "",
561         HANGUL_CHARSET, HANGUL_CHARSET,
562         TS_TRUE, TS_TRUE
563     },
564     /* Entry #32: HANGUL_CHARSET and fixed-pitch */
565     {
566         "",
567         HANGUL_CHARSET, HANGUL_CHARSET,
568         TS_UNKNOWN, TS_FALSE,
569         FALSE, TS_UNKNOWN,
570         FALSE, TS_UNKNOWN,
571         FALSE, TS_UNKNOWN,
572         TS_TRUE, TS_TRUE
573     },
574     /* Entry #33: JOHAB_CHARSET (Korean) */
575     {
576         "",
577         JOHAB_CHARSET, JOHAB_CHARSET,
578         TS_UNKNOWN, TS_UNKNOWN
579     },
580     /* Entry #34: JOHAB_CHARSET and bold */
581     {
582         "",
583         JOHAB_CHARSET, JOHAB_CHARSET,
584         TS_TRUE, TS_TRUE
585     },
586     /* Entry #35: JOHAB_CHARSET and fixed-pitch */
587     {
588         "",
589         JOHAB_CHARSET, JOHAB_CHARSET,
590         TS_UNKNOWN, TS_UNKNOWN,
591         FALSE, TS_UNKNOWN,
592         FALSE, TS_UNKNOWN,
593         FALSE, TS_UNKNOWN,
594         TS_TRUE, TS_TRUE
595     },
596     /* Entry #36: THAI_CHARSET (Thai) */
597     {
598         "",
599         THAI_CHARSET, THAI_CHARSET,
600         TS_UNKNOWN, TS_FALSE
601     },
602     /* Entry #37: THAI_CHARSET and bold */
603     {
604         "",
605         THAI_CHARSET, THAI_CHARSET,
606         TS_TRUE, TS_TRUE
607     },
608     /* Entry #38: THAI_CHARSET and fixed-pitch */
609     {
610         "",
611         THAI_CHARSET, THAI_CHARSET,
612         TS_UNKNOWN, TS_FALSE,
613         FALSE, TS_UNKNOWN,
614         FALSE, TS_UNKNOWN,
615         FALSE, TS_UNKNOWN,
616         TS_TRUE, TS_TRUE
617     },
618     /* Entry #39: GREEK_CHARSET (Greek) */
619     {
620         "",
621         GREEK_CHARSET, GREEK_CHARSET,
622         TS_UNKNOWN, TS_FALSE
623     },
624     /* Entry #40: GREEK_CHARSET and bold */
625     {
626         "",
627         GREEK_CHARSET, GREEK_CHARSET,
628         TS_TRUE, TS_TRUE
629     },
630     /* Entry #41: GREEK_CHARSET and italic */
631     {
632         "",
633         GREEK_CHARSET, GREEK_CHARSET,
634         TS_UNKNOWN, TS_FALSE,
635         TRUE, TS_TRUE
636     },
637     /* Entry #42: GREEK_CHARSET and fixed-pitch */
638     {
639         "",
640         GREEK_CHARSET, GREEK_CHARSET,
641         TS_UNKNOWN, TS_FALSE,
642         FALSE, TS_UNKNOWN,
643         FALSE, TS_UNKNOWN,
644         FALSE, TS_UNKNOWN,
645         TS_TRUE, TS_TRUE
646     },
647     /* Entry #43: "Marlett" */
648     {
649         "Marlett",
650         DEFAULT_CHARSET, SYMBOL_CHARSET
651     },
652     /* Entry #43: "Arial" */
653     {
654         "Arial",
655         DEFAULT_CHARSET, DEFAULT_CHARSET,
656         TS_UNKNOWN, TS_FALSE,
657         FALSE, TS_UNKNOWN,
658         FALSE, TS_UNKNOWN,
659         FALSE, TS_UNKNOWN,
660         TS_UNKNOWN, TS_FALSE
661     },
662     /* Entry #44: "Courier" */
663     {
664         "Courier",
665         DEFAULT_CHARSET, DEFAULT_CHARSET,
666         TS_UNKNOWN, TS_FALSE,
667         FALSE, TS_UNKNOWN,
668         FALSE, TS_UNKNOWN,
669         FALSE, TS_UNKNOWN,
670         TS_UNKNOWN, TS_TRUE
671     }
672 };
673 
674 static void
675 Test_FontSelectionEntry(HDC hDC, UINT nIndex, FONT_SEL_TEST *Entry)
676 {
677     LOGFONTA        lf;
678     HFONT           hFont;
679     HGDIOBJ         hFontOld;
680     TEXTMETRICA     tm;
681 
682     ZeroMemory(&lf, sizeof(lf));
683 
684     if (Entry->FaceNameBefore[0])
685         lstrcpynA(lf.lfFaceName, Entry->FaceNameBefore, _countof(lf.lfFaceName));
686 
687     lf.lfCharSet = Entry->CharSetBefore;
688 
689     if (Entry->BoldBefore == TS_TRUE)
690         lf.lfWeight = FW_BOLD;
691     else if (Entry->BoldBefore == TS_FALSE)
692         lf.lfWeight = FW_NORMAL;
693     else
694         lf.lfWeight = FW_DONTCARE;
695 
696     lf.lfItalic = Entry->ItalicBefore;
697     lf.lfUnderline = Entry->UnderlineBefore;
698     lf.lfStrikeOut = Entry->StruckOutBefore;
699 
700     if (Entry->FixedPitchBefore == TS_TRUE)
701         lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
702     else if (Entry->FixedPitchBefore == TS_FALSE)
703         lf.lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE;
704     else
705         lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
706 
707     hFont = CreateFontIndirectA(&lf);
708     ok(hFont != NULL, "Entry #%u: hFont failed\n", nIndex);
709 
710     hFontOld = SelectObject(hDC, hFont);
711     {
712         ok(GetTextMetricsA(hDC, &tm), "Entry #%u: GetTextMetricsA failed\n", nIndex);
713 
714         if (Entry->CharSetAfter != DEFAULT_CHARSET)
715             ok(tm.tmCharSet == Entry->CharSetAfter, "Entry #%u: CharSet mismatched, it was %u\n", nIndex, tm.tmCharSet);
716 
717         if (Entry->BoldAfter == TS_TRUE)
718             ok(tm.tmWeight >= FW_BOLD, "Entry #%u: Weight was non-bold\n", nIndex);
719         else if (Entry->BoldAfter == TS_FALSE)
720             ok(tm.tmWeight <= FW_MEDIUM, "Entry #%u: Weight was bold\n", nIndex);
721 
722         if (Entry->ItalicAfter == TS_TRUE)
723             ok(tm.tmItalic, "Entry #%u: Italic was non-italic\n", nIndex);
724         else if (Entry->ItalicAfter == TS_FALSE)
725             ok(!tm.tmItalic, "Entry #%u: Italic was italic\n", nIndex);
726 
727         if (Entry->UnderlineAfter == TS_TRUE)
728             ok(tm.tmUnderlined, "Entry #%u: Underlined was FALSE\n", nIndex);
729         else if (Entry->UnderlineAfter == TS_FALSE)
730             ok(!tm.tmUnderlined, "Entry #%u: Underlined was TRUE\n", nIndex);
731 
732         if (Entry->StruckOutAfter == TS_TRUE)
733             ok(tm.tmStruckOut, "Entry #%u: Struck-out was FALSE\n", nIndex);
734         else if (Entry->StruckOutAfter == TS_FALSE)
735             ok(!tm.tmStruckOut, "Entry #%u: Struck-out was TRUE\n", nIndex);
736 #if 0 // FIXME: fails on WHS testbot
737         if (Entry->FixedPitchAfter == TS_TRUE)
738             ok(!(tm.tmPitchAndFamily & _TMPF_VAR_PITCH), "Entry #%u: Pitch mismatched, it was non-fixed-pitch\n", nIndex);
739         else if (Entry->FixedPitchAfter == TS_FALSE)
740             ok((tm.tmPitchAndFamily & _TMPF_VAR_PITCH), "Entry #%u: Pitch mismatched, it was fixed-pitch\n", nIndex);
741 #endif
742     }
743     SelectObject(hDC, hFontOld);
744     DeleteObject(hFont);
745 }
746 
747 static void
748 Test_FontSelection(void)
749 {
750     UINT nIndex;
751     HDC hDC;
752 
753     hDC = CreateCompatibleDC(NULL);
754     for (nIndex = 0; nIndex < _countof(g_Entries); ++nIndex)
755     {
756         if (!is_charset_font_installed(hDC, g_Entries[nIndex].CharSetBefore))
757             skip("charset not available: 0x%x\n", g_Entries[nIndex].CharSetBefore);
758         else
759             Test_FontSelectionEntry(hDC, nIndex, g_Entries + nIndex);
760     }
761     DeleteDC(hDC);
762 }
763 
764 
765 START_TEST(CreateFontIndirect)
766 {
767     Test_CreateFontIndirectA();
768     Test_CreateFontIndirectW();
769     Test_CreateFontIndirectExA();
770     Test_CreateFontIndirectExW();
771     Test_FontPresence();
772     Test_FontSelection();
773 }
774 
775