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