Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/gdi32/tests/font.c | 198 +++++++++++++++++++++++++++++++++------- 1 file changed, 165 insertions(+), 33 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 4f10e2f38d..888335809d 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -20,6 +20,7 @@ */
#include <stdarg.h> +#include <stdio.h> #include <assert.h>
#include "windef.h" @@ -4254,25 +4255,33 @@ todo_wine DeleteDC(hdc); }
-static void test_RealizationInfo(void) +struct font_realization_info { - struct font_realization_info { - DWORD size; - DWORD flags; - DWORD cache_num; - DWORD instance_id; - DWORD unk; - WORD face_index; - WORD simulations; - }; + DWORD size; + DWORD flags; + DWORD cache_num; + DWORD instance_id; + DWORD unk; + WORD face_index; + WORD simulations; +}; + +struct file_info +{ + FILETIME time; + LARGE_INTEGER size; + WCHAR path[MAX_PATH]; +};
+static void test_RealizationInfo(void) +{ struct realization_info_t { DWORD flags; DWORD cache_num; DWORD instance_id; }; - + struct file_info file_info; HDC hdc; DWORD info[4], info2[10]; BOOL r, have_file = FALSE; @@ -4281,12 +4290,6 @@ static void test_RealizationInfo(void) DWORD needed, read; HANDLE h; BYTE file[16], data[14]; - struct file_info - { - FILETIME time; - LARGE_INTEGER size; - WCHAR path[MAX_PATH]; - } file_info; FILETIME time; LARGE_INTEGER size;
@@ -5049,9 +5052,14 @@ static void *load_font(const char *font_name, DWORD *font_size) HANDLE file, mapping; void *font;
- if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL; - strcat(file_name, "\fonts\"); - strcat(file_name, font_name); + if (font_name[1] == ':') + strcpy(file_name, font_name); + else + { + if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL; + strcat(file_name, "\fonts\"); + strcat(file_name, font_name); + }
file = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); if (file == INVALID_HANDLE_VALUE) return NULL; @@ -5072,8 +5080,70 @@ static void *load_font(const char *font_name, DWORD *font_size) return font; }
+static void test_realization_info(const char *name, DWORD size, BOOL is_memory_resource) +{ + struct font_realization_info info; + struct file_info file_info; + HFONT hfont, hfont_prev; + BYTE data[16]; + DWORD needed; + LOGFONTA lf; + BOOL ret; + HDC hdc; + + if (!pGetFontRealizationInfo) + return; + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = 72; + strcpy(lf.lfFaceName, name); + + hfont = CreateFontIndirectA(&lf); + ok(hfont != 0, "Failed to create a font, %u.\n", GetLastError()); + + hdc = GetDC(NULL); + + hfont_prev = SelectObject(hdc, hfont); + ok(hfont_prev != NULL, "Failed to select font.\n"); + + memset(&info, 0xcc, sizeof(info)); + info.size = sizeof(info); + ret = pGetFontRealizationInfo(hdc, (DWORD *)&info); + ok(ret != 0, "Unexpected return value %d.\n", ret); + + ok((info.flags & 0xf) == 0x3, "Unexpected flags %#x.\n", info.flags); + ok(info.cache_num != 0, "Unexpected cache num %u.\n", info.cache_num); + ok(info.instance_id != 0, "Unexpected instance id %u.\n", info.instance_id); + ok(info.simulations == 0, "Unexpected simulations %#x.\n", info.simulations); + ok(info.face_index == 0, "Unexpected face index %u.\n", info.face_index); + + needed = 0; + memset(&file_info, 0xcc, sizeof(file_info)); + ret = pGetFontFileInfo(info.instance_id, 0, &file_info, sizeof(file_info), &needed); + ok(ret != 0 || broken(GetLastError() == ERROR_NOACCESS), "Failed to get font file info, ret %d gle %d.\n", ret, GetLastError()); + if (ret) + { + todo_wine_if(is_memory_resource) + ok(is_memory_resource ? file_info.size.QuadPart == size : file_info.size.QuadPart > 0, "Unexpected file size.\n"); + ok(is_memory_resource ? !file_info.path[0] : file_info.path[0], "Unexpected file path %s.\n", + wine_dbgstr_w(file_info.path)); + } + +if (pGetFontFileData) +{ + memset(data, 0xcc, sizeof(data)); + ret = pGetFontFileData(info.instance_id, 0, 16, data, sizeof(data)); + ok(ret != 0, "Failed to get font file data, %d\n", GetLastError()); + ok(*(DWORD *)data == 0x1000000, "Unexpected sfnt header version %#x.\n", *(DWORD *)data); +} + SelectObject(hdc, hfont_prev); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); +} + static void test_AddFontMemResource(void) { + char ttf_name[MAX_PATH]; void *font; DWORD font_size, num_fonts; HANDLE ret; @@ -5085,13 +5155,6 @@ static void test_AddFontMemResource(void) return; }
- font = load_font("sserife.fon", &font_size); - if (!font) - { - skip("Unable to locate and load font sserife.fon\n"); - return; - } - SetLastError(0xdeadbeef); ret = pAddFontMemResourceEx(NULL, 0, NULL, NULL); ok(!ret, "AddFontMemResourceEx should fail\n"); @@ -5120,6 +5183,42 @@ static void test_AddFontMemResource(void) "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+ /* Now with scalable font */ + bRet = write_ttf_file("wine_test.ttf", ttf_name); + ok(bRet, "Failed to create test font file.\n"); + + font = load_font(ttf_name, &font_size); + ok(font != NULL, "Failed to map font file.\n"); + + bRet = is_truetype_font_installed("wine_test"); + ok(!bRet, "Font wine_test should not be enumerated.\n"); + + num_fonts = 0; + ret = pAddFontMemResourceEx(font, font_size, NULL, &num_fonts); + ok(ret != 0, "Failed to add resource, %d.\n", GetLastError()); + ok(num_fonts == 1, "Unexpected number of fonts %u.\n", num_fonts); + + bRet = is_truetype_font_installed("wine_test"); +todo_wine + ok(!bRet, "Font wine_test should not be enumerated.\n"); + + test_realization_info("wine_test", font_size, TRUE); + + bRet = pRemoveFontMemResourceEx(ret); + ok(bRet, "RemoveFontMemResourceEx error %d\n", GetLastError()); + + free_font(font); + + bRet = DeleteFileA(ttf_name); + ok(bRet, "Failed to delete font file, %d.\n", GetLastError()); + + font = load_font("sserife.fon", &font_size); + if (!font) + { + skip("Unable to locate and load font sserife.fon\n"); + return; + } + SetLastError(0xdeadbeef); ret = pAddFontMemResourceEx(font, 0, NULL, NULL); ok(!ret, "AddFontMemResourceEx should fail\n"); @@ -5839,6 +5938,7 @@ static void test_CreateScalableFontResource(void) test_GetGlyphOutline_empty_contour(); test_GetGlyphOutline_metric_clipping(); test_fstype_fixup(); + test_realization_info("wine_test", 0, FALSE);
ret = pRemoveFontResourceExA(fot_name, FR_PRIVATE, 0); ok(!ret, "RemoveFontResourceEx() with not matching flags should fail\n"); @@ -6859,8 +6959,31 @@ static void test_long_names(void)
START_TEST(font) { + static const char *test_names[] = + { + "AddFontMemResource", + "vertical_font", + "CreateScalableFontResource", + }; + char path_name[MAX_PATH]; + STARTUPINFOA startup; + char **argv; + int argc, i; + init();
+ argc = winetest_get_mainargs(&argv); + if (argc >= 3) + { + if (!strcmp(argv[2], "AddFontMemResource")) + test_AddFontMemResource(); + else if (!strcmp(argv[2], "vertical_font")) + test_vertical_font(); + else if (!strcmp(argv[2], "CreateScalableFontResource")) + test_CreateScalableFontResource(); + return; + } + test_stock_fonts(); test_logfont(); test_bitmap_font(); @@ -6879,7 +7002,6 @@ START_TEST(font) test_nonexistent_font(); test_orientation(); test_height_selection(); - test_AddFontMemResource(); test_EnumFonts(); test_EnumFonts_subst();
@@ -6923,9 +7045,19 @@ START_TEST(font) test_GetCharWidthI(); test_long_names();
- /* These tests should be last test until RemoveFontResource - * is properly implemented. - */ - test_vertical_font(); - test_CreateScalableFontResource(); + /* These tests run in separate processes until RemoveFontResource */ + winetest_get_mainargs( &argv ); + for (i = 0; i < ARRAY_SIZE(test_names); ++i) + { + PROCESS_INFORMATION info; + + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + sprintf(path_name, "%s font %s", argv[0], test_names[i]); + ok(CreateProcessA(NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), + "CreateProcess failed.\n"); + winetest_wait_child_process(info.hProcess); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + } }