/* * PROJECT: ReactOS API tests * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Test for EnumFontFamilies[Ex] * PROGRAMMERS: Thomas Faber */ #include "precomp.h" static BYTE ContextContinue; static BYTE ContextStop; static int EnumProcCalls; static ENUMLOGFONTA LastFontA; static ENUMLOGFONTW LastFontW; typedef int WRAP_ENUM_FONT_FAMILIES(_In_ HDC, _In_ PCWSTR, _In_ PVOID, _In_ LPARAM); typedef WRAP_ENUM_FONT_FAMILIES *PWRAP_ENUM_FONT_FAMILIES; static int WrapEnumFontFamiliesA( _In_ HDC hdc, _In_ PCWSTR Family, _In_ PVOID EnumProc, _In_ LPARAM lParam) { char FamilyA[100]; WideCharToMultiByte(CP_ACP, 0, Family, -1, FamilyA, sizeof(FamilyA), NULL, NULL); return EnumFontFamiliesA(hdc, FamilyA, EnumProc, lParam); } static int WrapEnumFontFamiliesW( _In_ HDC hdc, _In_ PCWSTR Family, _In_ PVOID EnumProc, _In_ LPARAM lParam) { return EnumFontFamiliesW(hdc, Family, EnumProc, lParam); } static int WrapEnumFontFamiliesExA( _In_ HDC hdc, _In_ PCWSTR Family, _In_ PVOID EnumProc, _In_ LPARAM lParam) { LOGFONTA lf; ZeroMemory(&lf, sizeof(lf)); lf.lfCharSet = DEFAULT_CHARSET; lf.lfPitchAndFamily = 0; WideCharToMultiByte(CP_ACP, 0, Family, -1, lf.lfFaceName, sizeof(lf.lfFaceName), NULL, NULL); return EnumFontFamiliesExA(hdc, &lf, EnumProc, lParam, 0); } static int WrapEnumFontFamiliesExW( _In_ HDC hdc, _In_ PCWSTR Family, _In_ PVOID EnumProc, _In_ LPARAM lParam) { LOGFONTW lf; ZeroMemory(&lf, sizeof(lf)); lf.lfCharSet = DEFAULT_CHARSET; lf.lfPitchAndFamily = 0; StringCbCopyW(lf.lfFaceName, sizeof(lf.lfFaceName), Family); return EnumFontFamiliesExW(hdc, &lf, EnumProc, lParam, 0); } static int CALLBACK EnumProcA( _In_ const LOGFONTA *elf, _In_ const TEXTMETRICA *ntm, _In_ DWORD FontType, _In_ LPARAM lParam) { EnumProcCalls++; ok(lParam == (LPARAM)&ContextContinue || lParam == (LPARAM)&ContextStop, "Context is %p, expected %p or %p\n", (PVOID)lParam, &ContextContinue, &ContextStop); LastFontA = *(ENUMLOGFONTA *)elf; return lParam == (LPARAM)&ContextContinue ? 7 : 0; } static int CALLBACK EnumProcW( _In_ const LOGFONTW *elf, _In_ const TEXTMETRICW *ntm, _In_ DWORD FontType, _In_ LPARAM lParam) { EnumProcCalls++; ok(lParam == (LPARAM)&ContextContinue || lParam == (LPARAM)&ContextStop, "Context is %p, expected %p or %p\n", (PVOID)lParam, &ContextContinue, &ContextStop); LastFontW = *(ENUMLOGFONTW *)elf; return lParam == (LPARAM)&ContextContinue ? 7 : 0; } static void TestEnumFontFamilies( _In_ HDC hdc, _In_ PCWSTR FontName, _In_ BOOLEAN ExpectToFind) { const struct { PWRAP_ENUM_FONT_FAMILIES Wrapper; PCSTR Name; BOOLEAN Wide; } *fun, functions[] = { { WrapEnumFontFamiliesA, "EnumFontFamiliesA", FALSE }, { WrapEnumFontFamiliesW, "EnumFontFamiliesW", TRUE }, { WrapEnumFontFamiliesExA, "EnumFontFamiliesExA", FALSE }, { WrapEnumFontFamiliesExW, "EnumFontFamiliesExW", TRUE }, }; const struct { PVOID Context; PCSTR Description; } *ctx, contexts[] = { { &ContextContinue, "Continue" }, { &ContextStop, "Stop" }, }; int ret; DWORD error; unsigned iFunction; unsigned iContext; for (iContext = 0; iContext < _countof(contexts); iContext++) { ctx = &contexts[iContext]; for (iFunction = 0; iFunction < _countof(functions); iFunction++) { fun = &functions[iFunction]; EnumProcCalls = 0; SetLastError(0xdeadbeef); ret = fun->Wrapper(hdc, FontName, fun->Wide ? (PVOID)EnumProcW : (PVOID)EnumProcA, (LPARAM)ctx->Context); error = GetLastError(); ok(error == 0xdeadbeef, "[%s, %s, '%ls'] error is %lu\n", fun->Name, ctx->Description, FontName, error); if (ExpectToFind) { if (ctx->Context == &ContextContinue) { ok(ret == 7, "[%s, %s, '%ls'] ret is %d, expected 7\n", fun->Name, ctx->Description, FontName, ret); ok(EnumProcCalls >= 1, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls); } else { ok(ret == 0, "[%s, %s, '%ls'] ret is %d, expected 0\n", fun->Name, ctx->Description, FontName, ret); ok(EnumProcCalls == 1, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls); } } else { ok(ret == 1, "[%s, %s, '%ls'] ret is %d, expected 1\n", fun->Name, ctx->Description, FontName, ret); ok(EnumProcCalls == 0, "[%s, %s, '%ls'] EnumProcCalls is %d\n", fun->Name, ctx->Description, FontName, EnumProcCalls); } } } } START_TEST(EnumFontFamilies) { HDC hdc; hdc = CreateCompatibleDC(NULL); if (!hdc) { skip("No DC\n"); return; } TestEnumFontFamilies(hdc, L"ThisFontDoesNotExist", FALSE); /* Basic fonts that should be installed */ TestEnumFontFamilies(hdc, L"MS Sans Serif", TRUE); TestEnumFontFamilies(hdc, L"Tahoma", TRUE); TestEnumFontFamilies(hdc, L"System", TRUE); /* Show case insensitivity */ TestEnumFontFamilies(hdc, L"tahOmA", TRUE); /* Special fonts that we have a hack for in win32k ;) */ TestEnumFontFamilies(hdc, L"Marlett", TRUE); TestEnumFontFamilies(hdc, L"Symbol", TRUE); TestEnumFontFamilies(hdc, L"VGA", FALSE); DeleteDC(hdc); }