Nikolay Sivov : gdi32: Implement GetFontFileInfo().

Alexandre Julliard julliard at wine.codeweavers.com
Mon Oct 5 10:30:26 CDT 2015


Module: wine
Branch: master
Commit: 6f7dfe2cea4fdb9b61775023659193421c920278
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6f7dfe2cea4fdb9b61775023659193421c920278

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Oct  4 12:48:48 2015 +0300

gdi32: Implement GetFontFileInfo().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>

---

 dlls/gdi32/freetype.c   | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/gdi32/gdi32.spec   |  1 +
 dlls/gdi32/tests/font.c | 19 ++++++++++---
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index de40d9f..33e196c 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')
@@ -8644,6 +8703,8 @@ static const struct gdi_dc_funcs freetype_funcs =
 
 #else /* HAVE_FREETYPE */
 
+struct font_fileinfo;
+
 /*************************************************************************/
 
 BOOL WineEngInit(void)
@@ -8687,4 +8748,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());




More information about the wine-cvs mailing list