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