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