[2/4] gdi32: Add a test for enumerating substituted fonts.
Dmitry Timoshkov
dmitry at baikal.ru
Fri Jul 17 04:23:14 CDT 2015
EnumFontFamilies(NULL) should not enumerate substituted fonts,
but EnumFontFamilies("MS Shell Dlg") should do.
---
dlls/gdi32/tests/font.c | 175 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 152 insertions(+), 23 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index f26c227..1a663d7 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1850,6 +1850,8 @@ static void test_height( HDC hdc, const struct font_data *fd )
}
SelectObject(hdc, old_hfont);
+ /* force GDI to use new font, otherwise Windows leaks the font reference */
+ GetTextMetricsA(hdc, &tm);
DeleteObject(hfont);
}
}
@@ -2002,6 +2004,7 @@ static void test_height_selection_vdmx( HDC hdc )
BYTE *ratio_rec;
char ttf_name[MAX_PATH];
void *res, *copy;
+ BOOL ret;
if (!pAddFontResourceExA)
{
@@ -2034,7 +2037,9 @@ static void test_height_selection_vdmx( HDC hdc )
test_height( hdc, data[i].fd );
pRemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
}
- DeleteFileA( ttf_name );
+ ret = DeleteFileA( ttf_name );
+ ok(ret || broken(!ret && GetLastError() == ERROR_ACCESS_DENIED),
+ "DeleteFile error %d\n", GetLastError());
}
}
@@ -3917,20 +3922,25 @@ static void test_nonexistent_font(void)
{ "Times New Roman Greek", 161 },
{ "Times New Roman TUR", 162 }
};
+ static const struct
+ {
+ const char *name;
+ int charset;
+ } shell_subst[] =
+ {
+ { "MS Shell Dlg", 186 },
+ { "MS Shell Dlg", 238 },
+ { "MS Shell Dlg", 204 },
+ { "MS Shell Dlg", 161 },
+ { "MS Shell Dlg", 162 }
+ };
LOGFONTA lf;
HDC hdc;
HFONT hfont;
CHARSETINFO csi;
- INT cs, expected_cs, i;
+ INT cs, expected_cs, i, ret;
char buf[LF_FACESIZE];
- if (!is_truetype_font_installed("Arial") ||
- !is_truetype_font_installed("Times New Roman"))
- {
- skip("Arial or Times New Roman not installed\n");
- return;
- }
-
expected_cs = GetACP();
if (!TranslateCharsetInfo(ULongToPtr(expected_cs), &csi, TCI_SRCCODEPAGE))
{
@@ -3940,7 +3950,48 @@ static void test_nonexistent_font(void)
expected_cs = csi.ciCharset;
trace("ACP %d -> charset %d\n", GetACP(), expected_cs);
- hdc = GetDC(0);
+ hdc = CreateCompatibleDC(0);
+
+ for (i = 0; i < sizeof(shell_subst)/sizeof(shell_subst[0]); i++)
+ {
+ ret = is_font_installed(shell_subst[i].name);
+ ok(ret || broken(!ret) /* win2000 */, "%s should be enumerated\n", shell_subst[i].name);
+ ret = is_truetype_font_installed(shell_subst[i].name);
+ ok(ret || broken(!ret) /* win2000 */, "%s should be enumerated\n", shell_subst[i].name);
+
+ memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = -13;
+ lf.lfWeight = FW_REGULAR;
+ strcpy(lf.lfFaceName, shell_subst[i].name);
+ hfont = CreateFontIndirectA(&lf);
+ hfont = SelectObject(hdc, hfont);
+ GetTextFaceA(hdc, sizeof(buf), buf);
+ ok(!lstrcmpiA(buf, shell_subst[i].name), "expected %s, got %s\n", shell_subst[i].name, buf);
+ cs = GetTextCharset(hdc);
+ ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d for font %s\n", cs, shell_subst[i].name);
+
+ DeleteObject(SelectObject(hdc, hfont));
+
+ memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = -13;
+ lf.lfWeight = FW_DONTCARE;
+ strcpy(lf.lfFaceName, shell_subst[i].name);
+ hfont = CreateFontIndirectA(&lf);
+ hfont = SelectObject(hdc, hfont);
+ GetTextFaceA(hdc, sizeof(buf), buf);
+ ok(!lstrcmpiA(buf, shell_subst[i].name), "expected %s, got %s\n", shell_subst[i].name, buf);
+ cs = GetTextCharset(hdc);
+ ok(cs == expected_cs || cs == ANSI_CHARSET, "expected %d, got %d for font %s\n", expected_cs, cs, shell_subst[i].name);
+ DeleteObject(SelectObject(hdc, hfont));
+ }
+
+ if (!is_truetype_font_installed("Arial") ||
+ !is_truetype_font_installed("Times New Roman"))
+ {
+ DeleteDC(hdc);
+ skip("Arial or Times New Roman not installed\n");
+ return;
+ }
memset(&lf, 0, sizeof(lf));
lf.lfHeight = 100;
@@ -3999,6 +4050,15 @@ todo_wine /* Wine uses Arial for all substitutions */
for (i = 0; i < sizeof(font_subst)/sizeof(font_subst[0]); i++)
{
+ ret = is_font_installed(font_subst[i].name);
+todo_wine
+ ok(ret || broken(!ret && !i) /* win2000 doesn't have Times New Roman Baltic substitution */,
+ "%s should be enumerated\n", font_subst[i].name);
+ ret = is_truetype_font_installed(font_subst[i].name);
+todo_wine
+ ok(ret || broken(!ret && !i) /* win2000 doesn't have Times New Roman Baltic substitution */,
+ "%s should be enumerated\n", font_subst[i].name);
+
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -13;
lf.lfWeight = FW_REGULAR;
@@ -4038,7 +4098,7 @@ todo_wine /* Wine uses Arial for all substitutions */
DeleteObject(SelectObject(hdc, hfont));
}
- ReleaseDC(0, hdc);
+ DeleteDC(hdc);
}
static void test_GdiRealizationInfo(void)
@@ -4868,7 +4928,6 @@ static void test_EnumFonts(void)
int ret;
LOGFONTA lf;
HDC hdc;
- struct enum_fullname_data efnd;
if (!is_truetype_font_installed("Arial"))
{
@@ -4929,26 +4988,95 @@ static void test_EnumFonts(void)
ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
ok(ret, "font Arial Italic Bold should not be enumerated\n");
- /* MS Shell Dlg and MS Shell Dlg 2 must exist */
+ DeleteDC(hdc);
+}
+
+static INT CALLBACK enum_ms_shell_dlg_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
+{
+ struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
+
+if (0) /* Disabled to limit console spam */
+ trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
+ lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
+
+ if (type != TRUETYPE_FONTTYPE) return 1;
+ if (strcmp(lf->lfFaceName, "MS Shell Dlg") != 0) return 1;
+
+ efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
+ return 0;
+}
+
+static INT CALLBACK enum_ms_shell_dlg2_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
+{
+ struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
+
+if (0) /* Disabled to limit console spam */
+ trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
+ lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
+
+ if (type != TRUETYPE_FONTTYPE) return 1;
+ if (strcmp(lf->lfFaceName, "MS Shell Dlg 2") != 0) return 1;
+
+ efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
+ return 0;
+}
+
+static void test_EnumFonts_subst(void)
+{
+ int ret;
+ LOGFONTA lf;
+ HDC hdc;
+ struct enum_fullname_data efnd;
+
+ ret = is_font_installed("MS Shell Dlg");
+ ok(ret, "MS Shell Dlg should be enumerated\n");
+ ret = is_truetype_font_installed("MS Shell Dlg");
+ ok(ret, "MS Shell Dlg should be enumerated as a TrueType font\n");
+
+ ret = is_font_installed("MS Shell Dlg 2");
+ ok(ret, "MS Shell Dlg 2 should be enumerated\n");
+ ret = is_truetype_font_installed("MS Shell Dlg 2");
+ ok(ret, "MS Shell Dlg 2 should be enumerated as a TrueType font\n");
+
+ hdc = CreateCompatibleDC(0);
+
+ memset(&efnd, 0, sizeof(efnd));
+ ret = EnumFontFamiliesExA(hdc, NULL, enum_ms_shell_dlg_proc, (LPARAM)&efnd, 0);
+ ok(ret, "MS Shell Dlg should not be enumerated\n");
+ ok(!efnd.total, "MS Shell Dlg should not be enumerated\n");
+
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET;
memset(&efnd, 0, sizeof(efnd));
strcpy(lf.lfFaceName, "MS Shell Dlg");
- ret = EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
- ok(ret, "font MS Shell Dlg is not enumerated\n");
- ret = strcmp((char*)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg");
- todo_wine ok(!ret, "expected MS Shell Dlg got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
- ret = strcmp((char*)efnd.elf[0].elfFullName, "MS Shell Dlg");
+ ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg_proc, (LPARAM)&efnd, 0);
+todo_wine
+ ok(!ret, "MS Shell Dlg should be enumerated\n");
+todo_wine
+ ok(efnd.total > 0, "MS Shell Dlg should be enumerated\n");
+ ret = strcmp((const char *)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg");
+todo_wine
+ ok(!ret, "expected MS Shell Dlg, got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
+ ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg");
ok(ret, "did not expect MS Shell Dlg\n");
memset(&efnd, 0, sizeof(efnd));
+ ret = EnumFontFamiliesExA(hdc, NULL, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
+ ok(ret, "MS Shell Dlg 2 should not be enumerated\n");
+ ok(!efnd.total, "MS Shell Dlg 2 should not be enumerated\n");
+
+ memset(&efnd, 0, sizeof(efnd));
strcpy(lf.lfFaceName, "MS Shell Dlg 2");
- ret = EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
- ok(ret, "font MS Shell Dlg 2 is not enumerated\n");
- ret = strcmp((char*)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg 2");
- todo_wine ok(!ret, "expected MS Shell Dlg 2 got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
- ret = strcmp((char*)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
+ ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
+todo_wine
+ ok(!ret, "MS Shell Dlg 2 should be enumerated\n");
+todo_wine
+ ok(efnd.total > 0, "MS Shell Dlg 2 should be enumerated\n");
+ ret = strcmp((const char *)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg 2");
+todo_wine
+ ok(!ret, "expected MS Shell Dlg 2, got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
+ ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
ok(ret, "did not expect MS Shell Dlg 2\n");
DeleteDC(hdc);
@@ -6229,6 +6357,7 @@ START_TEST(font)
test_height_selection();
test_AddFontMemResource();
test_EnumFonts();
+ test_EnumFonts_subst();
/* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
* I'd like to avoid them in this test.
--
2.4.5
More information about the wine-patches
mailing list