dwrite: Beginning implementation of IDWriteLocalFontFileLoader.

This commit is contained in:
Aric Stewart 2014-08-26 08:11:59 -07:00 committed by Alexandre Julliard
parent 78e02675ab
commit 95466a1c2f
4 changed files with 307 additions and 2 deletions

View file

@ -90,6 +90,7 @@ extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDE
extern void release_system_fontcollection(void) DECLSPEC_HIDDEN;
extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
extern HRESULT font_create_fontface(IDWriteFactory *iface, DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS sim_flags, IDWriteFontFace **font_face) DECLSPEC_HIDDEN;
/* Opentype font table functions */

View file

@ -1296,3 +1296,248 @@ HRESULT font_create_fontface(IDWriteFactory *iface, DWRITE_FONT_FACE_TYPE facety
return S_OK;
}
/* IDWriteLocalFontFileLoader and its required IDWriteFontFileStream */
struct dwrite_localfontfilestream
{
IDWriteFontFileStream IDWriteFontFileStream_iface;
LONG ref;
HANDLE handle;
};
struct dwrite_localfontfileloader {
IDWriteLocalFontFileLoader IDWriteLocalFontFileLoader_iface;
LONG ref;
};
static inline struct dwrite_localfontfileloader *impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader *iface)
{
return CONTAINING_RECORD(iface, struct dwrite_localfontfileloader, IDWriteLocalFontFileLoader_iface);
}
static inline struct dwrite_localfontfilestream *impl_from_IDWriteFontFileStream(IDWriteFontFileStream *iface)
{
return CONTAINING_RECORD(iface, struct dwrite_localfontfilestream, IDWriteFontFileStream_iface);
}
static HRESULT WINAPI localfontfilestream_QueryInterface(IDWriteFontFileStream *iface, REFIID riid, void **obj)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFileStream))
{
*obj = iface;
IDWriteFontFileStream_AddRef(iface);
return S_OK;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI localfontfilestream_AddRef(IDWriteFontFileStream *iface)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
return ref;
}
static ULONG WINAPI localfontfilestream_Release(IDWriteFontFileStream *iface)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
if (!ref)
{
if (This->handle != INVALID_HANDLE_VALUE)
CloseHandle(This->handle);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI localfontfilestream_ReadFileFragment(IDWriteFontFileStream *iface, void const **fragment_start, UINT64 offset, UINT64 fragment_size, void **fragment_context)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
LARGE_INTEGER distance;
DWORD bytes = fragment_size;
DWORD read;
TRACE("(%p)->(%p, %s, %s, %p)\n",This, fragment_start,
wine_dbgstr_longlong(offset), wine_dbgstr_longlong(fragment_size), fragment_context);
*fragment_context = NULL;
distance.QuadPart = offset;
if (!SetFilePointerEx(This->handle, distance, NULL, FILE_BEGIN))
return E_FAIL;
*fragment_start = *fragment_context = heap_alloc(bytes);
if (!*fragment_context)
return E_FAIL;
if (!ReadFile(This->handle, *fragment_context, bytes, &read, NULL))
{
heap_free(*fragment_context);
return E_FAIL;
}
return S_OK;
}
static void WINAPI localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream *iface, void *fragment_context)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
TRACE("(%p)->(%p)\n", This, fragment_context);
heap_free(fragment_context);
}
static HRESULT WINAPI localfontfilestream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
LARGE_INTEGER li;
TRACE("(%p)->(%p)\n",This, size);
GetFileSizeEx(This->handle, &li);
*size = li.QuadPart;
return S_OK;
}
static HRESULT WINAPI localfontfilestream_GetLastWriteTime(IDWriteFontFileStream *iface, UINT64 *last_writetime)
{
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
FIXME("(%p)->(%p): stub\n",This, last_writetime);
*last_writetime = 0;
return E_NOTIMPL;
}
static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl =
{
localfontfilestream_QueryInterface,
localfontfilestream_AddRef,
localfontfilestream_Release,
localfontfilestream_ReadFileFragment,
localfontfilestream_ReleaseFileFragment,
localfontfilestream_GetFileSize,
localfontfilestream_GetLastWriteTime
};
static HRESULT create_localfontfilestream(HANDLE handle, IDWriteFontFileStream** iface)
{
struct dwrite_localfontfilestream *This = heap_alloc(sizeof(struct dwrite_localfontfilestream));
if (!This)
return E_OUTOFMEMORY;
This->ref = 1;
This->handle = handle;
This->IDWriteFontFileStream_iface.lpVtbl = &localfontfilestreamvtbl;
*iface = &This->IDWriteFontFileStream_iface;
return S_OK;
}
static HRESULT WINAPI localfontfileloader_QueryInterface(IDWriteLocalFontFileLoader *iface, REFIID riid, void **obj)
{
struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFileLoader) || IsEqualIID(riid, &IID_IDWriteLocalFontFileLoader))
{
*obj = iface;
IDWriteLocalFontFileLoader_AddRef(iface);
return S_OK;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI localfontfileloader_AddRef(IDWriteLocalFontFileLoader *iface)
{
struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
return ref;
}
static ULONG WINAPI localfontfileloader_Release(IDWriteLocalFontFileLoader *iface)
{
struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(%d)\n", This, ref);
if (!ref)
heap_free(This);
return ref;
}
static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFileLoader *iface, const void *fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileStream **fontFileStream)
{
HANDLE handle;
struct dwrite_localfontfileloader *This = impl_from_IDWriteLocalFontFileLoader(iface);
const WCHAR *name = (const WCHAR*)fontFileReferenceKey;
TRACE("(%p)->(%p, %i, %p)\n",This, fontFileReferenceKey, fontFileReferenceKeySize, fontFileStream);
TRACE("name: %s\n",debugstr_w(name));
handle = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
return E_FAIL;
return create_localfontfilestream(handle, fontFileStream);
}
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;
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)
return E_INVALIDARG;
lstrcpynW((WCHAR*)key, path, key_size);
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;
}
static const struct IDWriteLocalFontFileLoaderVtbl localfontfileloadervtbl = {
localfontfileloader_QueryInterface,
localfontfileloader_AddRef,
localfontfileloader_Release,
localfontfileloader_CreateStreamFromKey,
localfontfileloader_GetFilePathLengthFromKey,
localfontfileloader_GetFilePathFromKey,
localfontfileloader_GetLastWriteTimeFromKey
};
HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface)
{
struct dwrite_localfontfileloader *This = heap_alloc(sizeof(struct dwrite_localfontfileloader));
if (!This)
return E_OUTOFMEMORY;
This->ref = 1;
This->IDWriteLocalFontFileLoader_iface.lpVtbl = &localfontfileloadervtbl;
*iface = &This->IDWriteLocalFontFileLoader_iface;
return S_OK;
}

View file

@ -363,6 +363,8 @@ struct dwritefactory{
IDWriteFactory IDWriteFactory_iface;
LONG ref;
IDWriteLocalFontFileLoader* localfontfileloader;
IDWriteFontCollectionLoader **loaders;
LONG loader_count;
IDWriteFontFileLoader **file_loaders;
@ -410,6 +412,8 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface)
if (!ref) {
int i;
if (This->localfontfileloader)
IDWriteLocalFontFileLoader_Release(This->localfontfileloader);
for (i = 0; i < This->loader_count; i++)
if (This->loaders[i])
IDWriteFontCollectionLoader_Release(This->loaders[i]);
@ -501,9 +505,17 @@ 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);
FIXME("(%p)->(%s %p %p): stub\n", This, debugstr_w(path), writetime, font_file);
return E_NOTIMPL;
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(path), writetime, font_file);
if (!This->localfontfileloader)
{
hr = create_localfontfileloader(&This->localfontfileloader);
if (FAILED(hr))
return hr;
}
return create_font_file((IDWriteFontFileLoader*)This->localfontfileloader, path, sizeof(WCHAR) * (strlenW(path)+1), font_file);
}
static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory *iface,
@ -742,6 +754,7 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno
This->IDWriteFactory_iface.lpVtbl = &dwritefactoryvtbl;
This->ref = 1;
This->localfontfileloader = NULL;
This->loader_count = 2;
This->loaders = heap_alloc_zero(sizeof(*This->loaders) * 2);
This->file_loader_count = 2;

View file

@ -989,6 +989,51 @@ static void test_FontLoader(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
}
static void test_CreateFontFileReference(void)
{
DWORD written;
HANDLE file;
HRSRC res;
void *ptr;
HRESULT hr;
WCHAR font_name[] = {'w','i','n','e','_','t','e','s','t','_','f','o','n','t','.','t','t','f',0};
IDWriteFontFile *ffile = NULL;
BOOL support = 1;
DWRITE_FONT_FILE_TYPE type = 1;
DWRITE_FONT_FACE_TYPE face = 1;
UINT32 count = 1;
IDWriteFontFace *fface = NULL;
file = CreateFileW(font_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
ok( file != INVALID_HANDLE_VALUE, "file creation failed\n" );
if (file == INVALID_HANDLE_VALUE) return;
res = FindResourceA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(1), (LPCSTR)RT_RCDATA);
ok( res != 0, "couldn't find resource\n" );
ptr = LockResource( LoadResource( GetModuleHandleA(NULL), res ));
WriteFile( file, ptr, SizeofResource( GetModuleHandleA(NULL), res ), &written, NULL );
ok( written == SizeofResource( GetModuleHandleA(NULL), res ), "couldn't write resource\n" );
CloseHandle( file );
hr = IDWriteFactory_CreateFontFileReference(factory, font_name, NULL, &ffile);
ok(hr == S_OK, "got 0x%08x\n",hr);
IDWriteFontFile_Analyze(ffile, &support, &type, &face, &count);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(support == TRUE, "got %i\n", support);
ok(type == DWRITE_FONT_FILE_TYPE_TRUETYPE, "got %i\n", type);
ok(face == DWRITE_FONT_FACE_TYPE_TRUETYPE, "got %i\n", face);
ok(count == 1, "got %i\n", count);
hr = IDWriteFactory_CreateFontFace(factory, face, 1, &ffile, 0, 0, &fface);
ok(hr == S_OK, "got 0x%08x\n",hr);
IDWriteFontFace_Release(fface);
IDWriteFontFile_Release(ffile);
DeleteFileW(font_name);
}
START_TEST(font)
{
HRESULT hr;
@ -1011,6 +1056,7 @@ START_TEST(font)
test_ConvertFontFaceToLOGFONT();
test_CustomFontCollection();
test_FontLoader();
test_CreateFontFileReference();
IDWriteFactory_Release(factory);
}