Nikolay Sivov : dwrite: Implement compatible reference key for local files and remaining loader methods.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Nov 17 07:43:45 CST 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Nov 15 19:19:00 2014 +0300

dwrite: Implement compatible reference key for local files and remaining loader methods.

---

 dlls/dwrite/dwrite_private.h |  1 +
 dlls/dwrite/font.c           | 71 ++++++++++++++++++++++++++++++++++++--------
 dlls/dwrite/main.c           | 16 ++++++++--
 dlls/dwrite/tests/font.c     | 39 ++++++++++++++++++++++--
 4 files changed, 110 insertions(+), 17 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index d1c42ce..3b1d283 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -108,6 +108,7 @@ extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DE
 extern HRESULT create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace2**) DECLSPEC_HIDDEN;
 extern HRESULT create_font_collection(IDWriteFactory*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection**) DECLSPEC_HIDDEN;
 extern BOOL    is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
+extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*) DECLSPEC_HIDDEN;
 
 /* Opentype font table functions */
 extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 8bb39fa..a83baa7 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -1984,6 +1984,12 @@ struct dwrite_localfontfilestream
     HANDLE handle;
 };
 
+struct local_refkey
+{
+    FILETIME writetime;
+    WCHAR name[1];
+};
+
 struct dwrite_localfontfileloader {
     IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface;
     LONG ref;
@@ -2153,16 +2159,16 @@ static ULONG WINAPI localfontfileloader_Release(IDWriteLocalFontFileLoader *ifac
     return ref;
 }
 
-static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream)
+static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader *iface, const void *key, UINT32 key_size, IDWriteFontFileStream **fontFileStream)
 {
-    HANDLE handle;
     struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
-    const WCHAR *name = (const WCHAR*)fontFileReferenceKey;
+    const struct local_refkey *refkey = key;
+    HANDLE handle;
 
-    TRACE("(%p)->(%p, %i, %p)\n",This, fontFileReferenceKey, fontFileReferenceKeySize, fontFileStream);
+    TRACE("(%p)->(%p, %i, %p)\n", This, key, key_size, fontFileStream);
 
-    TRACE("name: %s\n",debugstr_w(name));
-    handle = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
+    TRACE("name: %s\n", debugstr_w(refkey->name));
+    handle = CreateFileW(refkey->name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
     if (handle == INVALID_HANDLE_VALUE)
@@ -2174,26 +2180,37 @@ static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFi
 static HRESULT WINAPI localfontfileloader_GetFilePathLengthFromKey(IDWriteLocalFontFileLoader *iface, void const *key, UINT32 key_size, UINT32 *length)
 {
     struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
-    TRACE("(%p)->(%p, %i, %p)\n",This, key, key_size, length);
-    *length = key_size;
+    const struct local_refkey *refkey = key;
+
+    TRACE("(%p)->(%p, %i, %p)\n", This, key, key_size, length);
+
+    *length = strlenW(refkey->name);
     return S_OK;
 }
 
 static HRESULT WINAPI localfontfileloader_GetFilePathFromKey(IDWriteLocalFontFileLoader *iface, void const *key, UINT32 key_size, WCHAR *path, UINT32 length)
 {
     struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
-    TRACE("(%p)->(%p, %i, %p, %i)\n",This, key, key_size, path, length);
-    if (length < key_size)
+    const struct local_refkey *refkey = key;
+
+    TRACE("(%p)->(%p, %i, %p, %i)\n", This, key, key_size, path, length);
+
+    if (length < strlenW(refkey->name))
         return E_INVALIDARG;
-    lstrcpynW((WCHAR*)key, path, key_size);
+
+    strcpyW(path, refkey->name);
     return S_OK;
 }
 
 static HRESULT WINAPI localfontfileloader_GetLastWriteTimeFromKey(IDWriteLocalFontFileLoader *iface, void const *key, UINT32 key_size, FILETIME *writetime)
 {
     struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
-    FIXME("(%p)->(%p, %i, %p):stub\n",This, key, key_size, writetime);
-    return E_NOTIMPL;
+    const struct local_refkey *refkey = key;
+
+    TRACE("(%p)->(%p, %i, %p)\n", This, key, key_size, writetime);
+
+    *writetime = refkey->writetime;
+    return S_OK;
 }
 
 static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl = {
@@ -2218,3 +2235,31 @@ HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface)
     *iface = &This->IDWriteLocalFontFileLoader_iface;
     return S_OK;
 }
+
+HRESULT get_local_refkey(const WCHAR *path, const FILETIME *writetime, void **key, UINT32 *size)
+{
+    struct local_refkey *refkey;
+
+    *size = FIELD_OFFSET(struct local_refkey, name) + (strlenW(path)+1)*sizeof(WCHAR);
+    *key = NULL;
+
+    refkey = heap_alloc(*size);
+    if (!refkey)
+        return E_OUTOFMEMORY;
+
+    if (writetime)
+        refkey->writetime = *writetime;
+    else {
+        WIN32_FILE_ATTRIBUTE_DATA info;
+
+        if (GetFileAttributesExW(path, GetFileExInfoStandard, &info))
+            refkey->writetime = info.ftLastWriteTime;
+        else
+            memset(&refkey->writetime, 0, sizeof(refkey->writetime));
+    }
+    strcpyW(refkey->name, path);
+
+    *key = refkey;
+
+    return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 2868c3b..1292086 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -686,8 +686,11 @@ static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactor
 static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory *iface,
     WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file)
 {
-    HRESULT hr;
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
+    UINT32 key_size;
+    HRESULT hr;
+    void *key;
+
     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(path), writetime, font_file);
 
     if (!This->localfontfileloader)
@@ -696,7 +699,16 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory *ifac
         if (FAILED(hr))
             return hr;
     }
-    return create_font_file((IDWriteFontFileLoader*)This->localfontfileloader, path, sizeof(WCHAR) * (strlenW(path)+1), font_file);
+
+    /* get a reference key used by local loader */
+    hr = get_local_refkey(path, writetime, &key, &key_size);
+    if (FAILED(hr))
+        return hr;
+
+    hr = create_font_file((IDWriteFontFileLoader*)This->localfontfileloader, key, key_size, font_file);
+    heap_free(key);
+
+    return hr;
 }
 
 static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory *iface,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 60d0d44..1fdb8d0 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -2218,15 +2218,26 @@ static void test_GetFaceNames(void)
     IDWriteFactory_Release(factory);
 }
 
+struct local_refkey
+{
+    FILETIME writetime;
+    WCHAR name[1];
+};
+
 static void test_TryGetFontTable(void)
 {
+    IDWriteLocalFontFileLoader *localloader;
+    WIN32_FILE_ATTRIBUTE_DATA info;
+    const struct local_refkey *key;
+    IDWriteFontFileLoader *loader;
     const void *table, *table2;
     IDWriteFontFace *fontface;
     void *context, *context2;
     IDWriteFactory *factory;
     IDWriteFontFile *file;
-    BOOL exists;
-    UINT32 size;
+    WCHAR buffW[MAX_PATH];
+    BOOL exists, ret;
+    UINT32 size, len;
     HRESULT hr;
 
     create_testfontfile(test_fontfile);
@@ -2236,6 +2247,30 @@ static void test_TryGetFontTable(void)
     hr = IDWriteFactory_CreateFontFileReference(factory, test_fontfile, NULL, &file);
     ok(hr == S_OK, "got 0x%08x\n",hr);
 
+    key = NULL;
+    size = 0;
+    hr = IDWriteFontFile_GetReferenceKey(file, (const void**)&key, &size);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(size != 0, "got %u\n", size);
+
+    ret = GetFileAttributesExW(test_fontfile, GetFileExInfoStandard, &info);
+    ok(ret, "got %d\n", ret);
+    ok(!memcmp(&info.ftLastWriteTime, &key->writetime, sizeof(key->writetime)), "got wrong write time\n");
+
+    hr = IDWriteFontFile_GetLoader(file, &loader);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDWriteFontFileLoader_QueryInterface(loader, &IID_IDWriteLocalFontFileLoader, (void**)&localloader);
+    IDWriteFontFileLoader_Release(loader);
+
+    hr = IDWriteLocalFontFileLoader_GetFilePathLengthFromKey(localloader, key, size, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(lstrlenW(key->name) == len, "path length %d\n", len);
+
+    hr = IDWriteLocalFontFileLoader_GetFilePathFromKey(localloader, key, size, buffW, sizeof(buffW)/sizeof(WCHAR));
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(!lstrcmpW(buffW, key->name), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(key->name));
+    IDWriteLocalFontFileLoader_Release(localloader);
+
     hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, 0, 0, &fontface);
     ok(hr == S_OK, "got 0x%08x\n",hr);
 




More information about the wine-cvs mailing list