1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS API tests
3c2c66affSColin Finck  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4c2c66affSColin Finck  * PURPOSE:         Test for EnumFontFamilies[Ex]
5c2c66affSColin Finck  * PROGRAMMERS:     Thomas Faber <thomas.faber@reactos.org>
6c2c66affSColin Finck  */
7c2c66affSColin Finck 
8*aee83c35SAmine Khaldi #include "precomp.h"
9c2c66affSColin Finck 
10c2c66affSColin Finck static BYTE ContextContinue;
11c2c66affSColin Finck static BYTE ContextStop;
12c2c66affSColin Finck 
13c2c66affSColin Finck static int EnumProcCalls;
14c2c66affSColin Finck static ENUMLOGFONTA LastFontA;
15c2c66affSColin Finck static ENUMLOGFONTW LastFontW;
16c2c66affSColin Finck 
17c2c66affSColin Finck typedef int WRAP_ENUM_FONT_FAMILIES(_In_ HDC, _In_ PCWSTR, _In_ PVOID, _In_ LPARAM);
18c2c66affSColin Finck typedef WRAP_ENUM_FONT_FAMILIES *PWRAP_ENUM_FONT_FAMILIES;
19c2c66affSColin Finck 
20c2c66affSColin Finck static
21c2c66affSColin Finck int
WrapEnumFontFamiliesA(_In_ HDC hdc,_In_ PCWSTR Family,_In_ PVOID EnumProc,_In_ LPARAM lParam)22c2c66affSColin Finck WrapEnumFontFamiliesA(
23c2c66affSColin Finck     _In_ HDC hdc,
24c2c66affSColin Finck     _In_ PCWSTR Family,
25c2c66affSColin Finck     _In_ PVOID EnumProc,
26c2c66affSColin Finck     _In_ LPARAM lParam)
27c2c66affSColin Finck {
28c2c66affSColin Finck     char FamilyA[100];
29c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, Family, -1, FamilyA, sizeof(FamilyA), NULL, NULL);
30c2c66affSColin Finck     return EnumFontFamiliesA(hdc, FamilyA, EnumProc, lParam);
31c2c66affSColin Finck }
32c2c66affSColin Finck 
33c2c66affSColin Finck static
34c2c66affSColin Finck int
WrapEnumFontFamiliesW(_In_ HDC hdc,_In_ PCWSTR Family,_In_ PVOID EnumProc,_In_ LPARAM lParam)35c2c66affSColin Finck WrapEnumFontFamiliesW(
36c2c66affSColin Finck     _In_ HDC hdc,
37c2c66affSColin Finck     _In_ PCWSTR Family,
38c2c66affSColin Finck     _In_ PVOID EnumProc,
39c2c66affSColin Finck     _In_ LPARAM lParam)
40c2c66affSColin Finck {
41c2c66affSColin Finck     return EnumFontFamiliesW(hdc, Family, EnumProc, lParam);
42c2c66affSColin Finck }
43c2c66affSColin Finck 
44c2c66affSColin Finck static
45c2c66affSColin Finck int
WrapEnumFontFamiliesExA(_In_ HDC hdc,_In_ PCWSTR Family,_In_ PVOID EnumProc,_In_ LPARAM lParam)46c2c66affSColin Finck WrapEnumFontFamiliesExA(
47c2c66affSColin Finck     _In_ HDC hdc,
48c2c66affSColin Finck     _In_ PCWSTR Family,
49c2c66affSColin Finck     _In_ PVOID EnumProc,
50c2c66affSColin Finck     _In_ LPARAM lParam)
51c2c66affSColin Finck {
52c2c66affSColin Finck     LOGFONTA lf;
53c2c66affSColin Finck 
54c2c66affSColin Finck     ZeroMemory(&lf, sizeof(lf));
55c2c66affSColin Finck     lf.lfCharSet = DEFAULT_CHARSET;
56c2c66affSColin Finck     lf.lfPitchAndFamily = 0;
57c2c66affSColin Finck     WideCharToMultiByte(CP_ACP, 0, Family, -1, lf.lfFaceName, sizeof(lf.lfFaceName), NULL, NULL);
58c2c66affSColin Finck     return EnumFontFamiliesExA(hdc, &lf, EnumProc, lParam, 0);
59c2c66affSColin Finck }
60c2c66affSColin Finck 
61c2c66affSColin Finck static
62c2c66affSColin Finck int
WrapEnumFontFamiliesExW(_In_ HDC hdc,_In_ PCWSTR Family,_In_ PVOID EnumProc,_In_ LPARAM lParam)63c2c66affSColin Finck WrapEnumFontFamiliesExW(
64c2c66affSColin Finck     _In_ HDC hdc,
65c2c66affSColin Finck     _In_ PCWSTR Family,
66c2c66affSColin Finck     _In_ PVOID EnumProc,
67c2c66affSColin Finck     _In_ LPARAM lParam)
68c2c66affSColin Finck {
69c2c66affSColin Finck     LOGFONTW lf;
70c2c66affSColin Finck 
71c2c66affSColin Finck     ZeroMemory(&lf, sizeof(lf));
72c2c66affSColin Finck     lf.lfCharSet = DEFAULT_CHARSET;
73c2c66affSColin Finck     lf.lfPitchAndFamily = 0;
74c2c66affSColin Finck     StringCbCopyW(lf.lfFaceName, sizeof(lf.lfFaceName), Family);
75c2c66affSColin Finck     return EnumFontFamiliesExW(hdc, &lf, EnumProc, lParam, 0);
76c2c66affSColin Finck }
77c2c66affSColin Finck 
78c2c66affSColin Finck static
79c2c66affSColin Finck int
80c2c66affSColin Finck CALLBACK
EnumProcA(_In_ const LOGFONTA * elf,_In_ const TEXTMETRICA * ntm,_In_ DWORD FontType,_In_ LPARAM lParam)81c2c66affSColin Finck EnumProcA(
82c2c66affSColin Finck     _In_ const LOGFONTA *elf,
83c2c66affSColin Finck     _In_ const TEXTMETRICA *ntm,
84c2c66affSColin Finck     _In_ DWORD FontType,
85c2c66affSColin Finck     _In_ LPARAM lParam)
86c2c66affSColin Finck {
87c2c66affSColin Finck     EnumProcCalls++;
88c2c66affSColin Finck 
89c2c66affSColin Finck     ok(lParam == (LPARAM)&ContextContinue ||
90c2c66affSColin Finck        lParam == (LPARAM)&ContextStop,
91c2c66affSColin Finck        "Context is %p, expected %p or %p\n",
92c2c66affSColin Finck        (PVOID)lParam, &ContextContinue, &ContextStop);
93c2c66affSColin Finck 
94c2c66affSColin Finck     LastFontA = *(ENUMLOGFONTA *)elf;
95c2c66affSColin Finck     return lParam == (LPARAM)&ContextContinue ? 7 : 0;
96c2c66affSColin Finck }
97c2c66affSColin Finck 
98c2c66affSColin Finck static
99c2c66affSColin Finck int
100c2c66affSColin Finck CALLBACK
EnumProcW(_In_ const LOGFONTW * elf,_In_ const TEXTMETRICW * ntm,_In_ DWORD FontType,_In_ LPARAM lParam)101c2c66affSColin Finck EnumProcW(
102c2c66affSColin Finck     _In_ const LOGFONTW *elf,
103c2c66affSColin Finck     _In_ const TEXTMETRICW *ntm,
104c2c66affSColin Finck     _In_ DWORD FontType,
105c2c66affSColin Finck     _In_ LPARAM lParam)
106c2c66affSColin Finck {
107c2c66affSColin Finck     EnumProcCalls++;
108c2c66affSColin Finck 
109c2c66affSColin Finck     ok(lParam == (LPARAM)&ContextContinue ||
110c2c66affSColin Finck        lParam == (LPARAM)&ContextStop,
111c2c66affSColin Finck        "Context is %p, expected %p or %p\n",
112c2c66affSColin Finck        (PVOID)lParam, &ContextContinue, &ContextStop);
113c2c66affSColin Finck 
114c2c66affSColin Finck     LastFontW = *(ENUMLOGFONTW *)elf;
115c2c66affSColin Finck     return lParam == (LPARAM)&ContextContinue ? 7 : 0;
116c2c66affSColin Finck }
117c2c66affSColin Finck 
118c2c66affSColin Finck static
119c2c66affSColin Finck void
TestEnumFontFamilies(_In_ HDC hdc,_In_ PCWSTR FontName,_In_ BOOLEAN ExpectToFind)120c2c66affSColin Finck TestEnumFontFamilies(
121c2c66affSColin Finck     _In_ HDC hdc,
122c2c66affSColin Finck     _In_ PCWSTR FontName,
123c2c66affSColin Finck     _In_ BOOLEAN ExpectToFind)
124c2c66affSColin Finck {
125c2c66affSColin Finck     const struct
126c2c66affSColin Finck     {
127c2c66affSColin Finck         PWRAP_ENUM_FONT_FAMILIES Wrapper;
128c2c66affSColin Finck         PCSTR Name;
129c2c66affSColin Finck         BOOLEAN Wide;
130c2c66affSColin Finck     } *fun, functions[] =
131c2c66affSColin Finck     {
132c2c66affSColin Finck         { WrapEnumFontFamiliesA,    "EnumFontFamiliesA",    FALSE },
133c2c66affSColin Finck         { WrapEnumFontFamiliesW,    "EnumFontFamiliesW",    TRUE },
134c2c66affSColin Finck         { WrapEnumFontFamiliesExA,  "EnumFontFamiliesExA",  FALSE },
135c2c66affSColin Finck         { WrapEnumFontFamiliesExW,  "EnumFontFamiliesExW",  TRUE },
136c2c66affSColin Finck     };
137c2c66affSColin Finck     const struct
138c2c66affSColin Finck     {
139c2c66affSColin Finck         PVOID Context;
140c2c66affSColin Finck         PCSTR Description;
141c2c66affSColin Finck     } *ctx, contexts[] =
142c2c66affSColin Finck     {
143c2c66affSColin Finck         { &ContextContinue, "Continue" },
144c2c66affSColin Finck         { &ContextStop,     "Stop" },
145c2c66affSColin Finck     };
146c2c66affSColin Finck     int ret;
147c2c66affSColin Finck     DWORD error;
148c2c66affSColin Finck     unsigned iFunction;
149c2c66affSColin Finck     unsigned iContext;
150c2c66affSColin Finck 
151c2c66affSColin Finck     for (iContext = 0; iContext < _countof(contexts); iContext++)
152c2c66affSColin Finck     {
153c2c66affSColin Finck         ctx = &contexts[iContext];
154c2c66affSColin Finck         for (iFunction = 0; iFunction < _countof(functions); iFunction++)
155c2c66affSColin Finck         {
156c2c66affSColin Finck             fun = &functions[iFunction];
157c2c66affSColin Finck             EnumProcCalls = 0;
158c2c66affSColin Finck             SetLastError(0xdeadbeef);
159c2c66affSColin Finck             ret = fun->Wrapper(hdc,
160c2c66affSColin Finck                                FontName,
161c2c66affSColin Finck                                fun->Wide ? (PVOID)EnumProcW : (PVOID)EnumProcA,
162c2c66affSColin Finck                                (LPARAM)ctx->Context);
163c2c66affSColin Finck             error = GetLastError();
164c2c66affSColin Finck             ok(error == 0xdeadbeef, "[%s, %s, '%ls'] error is %lu\n", fun->Name, ctx->Description, FontName, error);
165c2c66affSColin Finck             if (ExpectToFind)
166c2c66affSColin Finck             {
167c2c66affSColin Finck                 if (ctx->Context == &ContextContinue)
168c2c66affSColin Finck                 {
169c2c66affSColin Finck                     ok(ret == 7, "[%s, %s, '%ls'] ret is %d, expected 7\n", fun->Name, ctx->Description, FontName, ret);
170c2c66affSColin Finck                     ok(EnumProcCalls >= 1, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls);
171c2c66affSColin Finck                 }
172c2c66affSColin Finck                 else
173c2c66affSColin Finck                 {
174c2c66affSColin Finck                     ok(ret == 0, "[%s, %s, '%ls'] ret is %d, expected 0\n", fun->Name, ctx->Description, FontName, ret);
175c2c66affSColin Finck                     ok(EnumProcCalls == 1, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls);
176c2c66affSColin Finck                 }
177c2c66affSColin Finck             }
178c2c66affSColin Finck             else
179c2c66affSColin Finck             {
180c2c66affSColin Finck                 ok(ret == 1, "[%s, %s, '%ls'] ret is %d, expected 1\n", fun->Name, ctx->Description, FontName, ret);
181c2c66affSColin Finck                 ok(EnumProcCalls == 0, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls);
182c2c66affSColin Finck             }
183c2c66affSColin Finck         }
184c2c66affSColin Finck     }
185c2c66affSColin Finck }
186c2c66affSColin Finck 
START_TEST(EnumFontFamilies)187c2c66affSColin Finck START_TEST(EnumFontFamilies)
188c2c66affSColin Finck {
189c2c66affSColin Finck     HDC hdc;
190c2c66affSColin Finck 
191c2c66affSColin Finck     hdc = CreateCompatibleDC(NULL);
192c2c66affSColin Finck     if (!hdc)
193c2c66affSColin Finck     {
194c2c66affSColin Finck         skip("No DC\n");
195c2c66affSColin Finck         return;
196c2c66affSColin Finck     }
197c2c66affSColin Finck 
198c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"ThisFontDoesNotExist", FALSE);
199c2c66affSColin Finck     /* Basic fonts that should be installed */
200c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"MS Sans Serif", TRUE);
201c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"Tahoma", TRUE);
202c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"System", TRUE);
203c2c66affSColin Finck     /* Show case insensitivity */
204c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"tahOmA", TRUE);
205c2c66affSColin Finck     /* Special fonts that we have a hack for in win32k ;) */
206c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"Marlett", TRUE);
207c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"Symbol", TRUE);
208c2c66affSColin Finck     TestEnumFontFamilies(hdc, L"VGA", FALSE);
209c2c66affSColin Finck 
210c2c66affSColin Finck     DeleteDC(hdc);
211c2c66affSColin Finck }
212c2c66affSColin Finck 
213