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

This commit is contained in:
Nikolay Sivov 2014-11-15 19:19:00 +03:00 committed by Alexandre Julliard
parent 45d530461b
commit 53fb0cc711
4 changed files with 110 additions and 17 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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,

View file

@ -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);