[PATCH] gdi32: Implement GetFontFileInfo()
Nikolay Sivov
nsivov at codeweavers.com
Sun Oct 4 04:48:48 CDT 2015
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/gdi32/freetype.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++-
dlls/gdi32/gdi32.spec | 1 +
dlls/gdi32/tests/font.c | 19 +++++++++++---
3 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index de40d9f..fcaa131 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -364,6 +364,12 @@ typedef struct {
GdiFont *font;
} CHILD_FONT;
+struct font_fileinfo {
+ FILETIME writetime;
+ LARGE_INTEGER size;
+ WCHAR path[1];
+};
+
struct tagGdiFont {
struct list entry;
struct list unused_entry;
@@ -400,6 +406,7 @@ struct tagGdiFont {
const VOID *vert_feature;
DWORD cache_num;
DWORD instance_id;
+ struct font_fileinfo *fileinfo;
};
typedef struct {
@@ -4505,6 +4512,7 @@ static void free_font(GdiFont *font)
HeapFree(GetProcessHeap(), 0, child);
}
+ HeapFree(GetProcessHeap(), 0, font->fileinfo);
free_font_handle(font->instance_id);
if (font->ft_face) pFT_Done_Face(font->ft_face);
if (font->mapping) unmap_font_file( font->mapping );
@@ -5161,6 +5169,29 @@ static const VOID * get_GSUB_vert_feature(const GdiFont *font)
return feature;
}
+static void fill_fileinfo_from_face( GdiFont *font, Face *face )
+{
+ WIN32_FILE_ATTRIBUTE_DATA info;
+ int len;
+
+ if (!face->file)
+ {
+ font->fileinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font->fileinfo));
+ return;
+ }
+
+ len = strlenW(face->file);
+ font->fileinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
+ if (GetFileAttributesExW(face->file, GetFileExInfoStandard, &info))
+ {
+ font->fileinfo->writetime = info.ftLastWriteTime;
+ font->fileinfo->size.QuadPart = (LONGLONG)info.nFileSizeHigh << 32 | info.nFileSizeLow;
+ strcpyW(font->fileinfo->path, face->file);
+ }
+ else
+ memset(&font->fileinfo, 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
+}
+
/*************************************************************
* freetype_SelectFont
*/
@@ -5555,6 +5586,7 @@ found_face:
goto done;
}
+ fill_fileinfo_from_face( ret, face );
ret->ntmFlags = face->ntmFlags;
pick_charmap( ret->ft_face, ret->charset );
@@ -8238,7 +8270,7 @@ static BOOL freetype_GetFontRealizationInfo( PHYSDEV dev, void *ptr )
return dev->funcs->pGetFontRealizationInfo( dev, ptr );
}
- FIXME("(%p, %p): stub!\n", physdev->font, info);
+ TRACE("(%p, %p)\n", physdev->font, info);
info->flags = 1;
if(FT_IS_SCALABLE(physdev->font->ft_face))
@@ -8256,6 +8288,33 @@ static BOOL freetype_GetFontRealizationInfo( PHYSDEV dev, void *ptr )
}
/*************************************************************************
+ * GetFontFileInfo (GDI32.@)
+ */
+BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_fileinfo *info, DWORD size, DWORD *needed )
+{
+ struct font_handle_entry *entry = handle_entry( instance_id );
+ const GdiFont *font;
+
+ if (!entry)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ font = entry->obj;
+ *needed = sizeof(*info) + strlenW(font->fileinfo->path) * sizeof(WCHAR);
+ if (*needed > size)
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+
+ /* path is included too */
+ memcpy(info, font->fileinfo, *needed);
+ return TRUE;
+}
+
+/*************************************************************************
* Kerning support for TrueType fonts
*/
#define MS_KERN_TAG MS_MAKE_TAG('k', 'e', 'r', 'n')
@@ -8687,4 +8746,13 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
return TRUE;
}
+/*************************************************************************
+ * GetFontFileInfo (GDI32.@)
+ */
+BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_fileinfo *info, DWORD size, DWORD *needed)
+{
+ *needed = 0;
+ return FALSE;
+}
+
#endif /* HAVE_FREETYPE */
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 8bba686..7d837f6 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -279,6 +279,7 @@
@ stdcall GetEnhMetaFileW(wstr)
# @ stub GetFontAssocStatus
@ stdcall GetFontData(long long long ptr long)
+@ stdcall GetFontFileInfo(long long ptr long ptr)
@ stdcall GetFontLanguageInfo(long)
@ stdcall GetFontRealizationInfo(long ptr)
@ stub GetFontResourceInfo
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index dff0eb6..c7dd6e1 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -4177,14 +4177,14 @@ static void test_RealizationInfo(void)
ok((info[0] & 0xf) == 1, "info[0] = %x for the system font\n", info[0]);
ok(info[3] == 0xcccccccc, "structure longer than 3 dwords\n");
- if (!is_truetype_font_installed("Arial"))
+ if (!is_truetype_font_installed("Tahoma"))
{
skip("skipping GdiRealizationInfo with truetype font\n");
goto end;
}
memset(&lf, 0, sizeof(lf));
- strcpy(lf.lfFaceName, "Arial");
+ strcpy(lf.lfFaceName, "Tahoma");
lf.lfHeight = 20;
lf.lfWeight = FW_NORMAL;
hfont = CreateFontIndirectA(&lf);
@@ -4238,12 +4238,19 @@ static void test_RealizationInfo(void)
ok(info2[6] == 0xcccccccc, "structure longer than 6 dwords\n");
/* Test GetFontFileInfo() */
- if (pGetFontFileInfo) {
+ /* invalid font id */
+ SetLastError(0xdeadbeef);
+ r = pGetFontFileInfo(0xabababab, 0, &file_info, sizeof(file_info), &needed);
+ ok(r == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "ret %d gle %d\n", r, GetLastError());
+
+ needed = 0;
r = pGetFontFileInfo(fri->instance_id, 0, &file_info, sizeof(file_info), &needed);
ok(r != 0 || GetLastError() == ERROR_NOACCESS, "ret %d gle %d\n", r, GetLastError());
if (r)
{
+ ok(needed > 0 && needed < sizeof(file_info), "got needed size %u\n", needed);
+
h = CreateFileW(file_info.path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok(h != INVALID_HANDLE_VALUE, "Unable to open file %d\n", GetLastError());
@@ -4256,8 +4263,14 @@ static void test_RealizationInfo(void)
ReadFile(h, file, sizeof(file), &read, NULL);
CloseHandle(h);
have_file = TRUE;
+
+ /* shorter buffer */
+ SetLastError(0xdeadbeef);
+ r = pGetFontFileInfo(fri->instance_id, 0, &file_info, needed - 1, &needed);
+ ok(r == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "ret %d gle %d\n", r, GetLastError());
}
+ if (pGetFontFileData) {
/* Get bytes 2 - 16 using GetFontFileData */
r = pGetFontFileData(fri->instance_id, 0, 2, data, sizeof(data));
ok(r != 0, "ret 0 gle %d\n", GetLastError());
--
2.5.3
More information about the wine-patches
mailing list