dwrite: Implement IDWriteInMemoryFontFileLoader.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b4c0b77b03
commit
fb8226f639
|
@ -210,6 +210,7 @@ extern HRESULT create_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1**) DECLSPEC
|
|||
extern void fontface_detach_from_cache(IDWriteFontFace4*) DECLSPEC_HIDDEN;
|
||||
extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
|
||||
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Opentype font table functions */
|
||||
struct dwrite_font_props {
|
||||
|
|
|
@ -4480,6 +4480,32 @@ struct dwrite_localfontfileloader {
|
|||
|
||||
static struct dwrite_localfontfileloader local_fontfile_loader;
|
||||
|
||||
struct dwrite_inmemory_stream_data
|
||||
{
|
||||
LONG ref;
|
||||
IUnknown *owner;
|
||||
void *data;
|
||||
UINT32 size;
|
||||
};
|
||||
|
||||
struct dwrite_inmemory_filestream
|
||||
{
|
||||
IDWriteFontFileStream IDWriteFontFileStream_iface;
|
||||
LONG ref;
|
||||
|
||||
struct dwrite_inmemory_stream_data *data;
|
||||
};
|
||||
|
||||
struct dwrite_inmemory_fileloader
|
||||
{
|
||||
IDWriteInMemoryFontFileLoader IDWriteInMemoryFontFileLoader_iface;
|
||||
LONG ref;
|
||||
|
||||
struct dwrite_inmemory_stream_data **streams;
|
||||
UINT32 filecount;
|
||||
UINT32 capacity;
|
||||
};
|
||||
|
||||
static inline struct dwrite_localfontfileloader *impl_from_IDWriteLocalFontFileLoader(IDWriteLocalFontFileLoader *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct dwrite_localfontfileloader, IDWriteLocalFontFileLoader_iface);
|
||||
|
@ -4490,6 +4516,27 @@ static inline struct dwrite_localfontfilestream *impl_from_IDWriteFontFileStream
|
|||
return CONTAINING_RECORD(iface, struct dwrite_localfontfilestream, IDWriteFontFileStream_iface);
|
||||
}
|
||||
|
||||
static inline struct dwrite_inmemory_fileloader *impl_from_IDWriteInMemoryFontFileLoader(IDWriteInMemoryFontFileLoader *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct dwrite_inmemory_fileloader, IDWriteInMemoryFontFileLoader_iface);
|
||||
}
|
||||
|
||||
static inline struct dwrite_inmemory_filestream *inmemory_impl_from_IDWriteFontFileStream(IDWriteFontFileStream *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct dwrite_inmemory_filestream, IDWriteFontFileStream_iface);
|
||||
}
|
||||
|
||||
static void release_inmemory_stream(struct dwrite_inmemory_stream_data *stream)
|
||||
{
|
||||
if (InterlockedDecrement(&stream->ref) == 0) {
|
||||
if (stream->owner)
|
||||
IUnknown_Release(stream->owner);
|
||||
else
|
||||
heap_free(stream->data);
|
||||
heap_free(stream);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI localfontfilestream_QueryInterface(IDWriteFontFileStream *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
|
||||
|
@ -5967,3 +6014,273 @@ HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file
|
|||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfilestream_QueryInterface(IDWriteFontFileStream *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%s, %p)\n", stream, debugstr_guid(riid), obj);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IDWriteFontFileStream) || IsEqualIID(riid, &IID_IUnknown)) {
|
||||
*obj = iface;
|
||||
IDWriteFontFileStream_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*obj = NULL;
|
||||
|
||||
WARN("%s not implemented.\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI inmemoryfilestream_AddRef(IDWriteFontFileStream *iface)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
ULONG ref = InterlockedIncrement(&stream->ref);
|
||||
TRACE_(dwrite_file)("(%p)->(%u)\n", stream, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI inmemoryfilestream_Release(IDWriteFontFileStream *iface)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
ULONG ref = InterlockedDecrement(&stream->ref);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%u)\n", stream, ref);
|
||||
|
||||
if (!ref) {
|
||||
release_inmemory_stream(stream->data);
|
||||
heap_free(stream);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfilestream_ReadFileFragment(IDWriteFontFileStream *iface, void const **fragment_start,
|
||||
UINT64 offset, UINT64 fragment_size, void **fragment_context)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%p, 0x%s, 0x%s, %p)\n", stream, fragment_start,
|
||||
wine_dbgstr_longlong(offset), wine_dbgstr_longlong(fragment_size), fragment_context);
|
||||
|
||||
*fragment_context = NULL;
|
||||
|
||||
if ((offset >= stream->data->size - 1) || (fragment_size > stream->data->size - offset)) {
|
||||
*fragment_start = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
*fragment_start = (char *)stream->data->data + offset;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void WINAPI inmemoryfilestream_ReleaseFileFragment(IDWriteFontFileStream *iface, void *fragment_context)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%p)\n", stream, fragment_context);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfilestream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%p)\n", stream, size);
|
||||
|
||||
*size = stream->data->size;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfilestream_GetLastWriteTime(IDWriteFontFileStream *iface, UINT64 *last_writetime)
|
||||
{
|
||||
struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface);
|
||||
|
||||
TRACE_(dwrite_file)("(%p)->(%p)\n", stream, last_writetime);
|
||||
|
||||
*last_writetime = 0;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IDWriteFontFileStreamVtbl inmemoryfilestreamvtbl = {
|
||||
inmemoryfilestream_QueryInterface,
|
||||
inmemoryfilestream_AddRef,
|
||||
inmemoryfilestream_Release,
|
||||
inmemoryfilestream_ReadFileFragment,
|
||||
inmemoryfilestream_ReleaseFileFragment,
|
||||
inmemoryfilestream_GetFileSize,
|
||||
inmemoryfilestream_GetLastWriteTime,
|
||||
};
|
||||
|
||||
static HRESULT WINAPI inmemoryfontfileloader_QueryInterface(IDWriteInMemoryFontFileLoader *iface,
|
||||
REFIID riid, void **obj)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
|
||||
TRACE("(%p)->(%s, %p)\n", loader, debugstr_guid(riid), obj);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IDWriteInMemoryFontFileLoader) ||
|
||||
IsEqualIID(riid, &IID_IDWriteFontFileLoader) ||
|
||||
IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*obj = iface;
|
||||
IDWriteInMemoryFontFileLoader_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("%s not implemented.\n", debugstr_guid(riid));
|
||||
|
||||
*obj = NULL;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI inmemoryfontfileloader_AddRef(IDWriteInMemoryFontFileLoader *iface)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
ULONG ref = InterlockedIncrement(&loader->ref);
|
||||
TRACE("(%p)->(%u)\n", loader, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI inmemoryfontfileloader_Release(IDWriteInMemoryFontFileLoader *iface)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
ULONG ref = InterlockedDecrement(&loader->ref);
|
||||
|
||||
TRACE("(%p)->(%u)\n", loader, ref);
|
||||
|
||||
if (!ref) {
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < loader->filecount; i++)
|
||||
release_inmemory_stream(loader->streams[i]);
|
||||
heap_free(loader->streams);
|
||||
heap_free(loader);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfontfileloader_CreateStreamFromKey(IDWriteInMemoryFontFileLoader *iface,
|
||||
void const *key, UINT32 key_size, IDWriteFontFileStream **ret)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
struct dwrite_inmemory_filestream *stream;
|
||||
DWORD index;
|
||||
|
||||
TRACE("(%p)->(%p, %u, %p)\n", loader, key, key_size, ret);
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
if (key_size != sizeof(DWORD))
|
||||
return E_INVALIDARG;
|
||||
|
||||
index = *(DWORD *)key;
|
||||
|
||||
if (index >= loader->filecount)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!(stream = heap_alloc(sizeof(*stream))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
stream->IDWriteFontFileStream_iface.lpVtbl = &inmemoryfilestreamvtbl;
|
||||
stream->ref = 1;
|
||||
stream->data = loader->streams[index];
|
||||
InterlockedIncrement(&stream->data->ref);
|
||||
|
||||
*ret = &stream->IDWriteFontFileStream_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI inmemoryfontfileloader_CreateInMemoryFontFileReference(IDWriteInMemoryFontFileLoader *iface,
|
||||
IDWriteFactory *factory, void const *data, UINT32 data_size, IUnknown *owner, IDWriteFontFile **fontfile)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
struct dwrite_inmemory_stream_data *stream;
|
||||
DWORD key;
|
||||
|
||||
TRACE("(%p)->(%p, %p, %u, %p, %p)\n", loader, factory, data, data_size, owner, fontfile);
|
||||
|
||||
*fontfile = NULL;
|
||||
|
||||
if (loader->filecount == loader->capacity) {
|
||||
if (loader->streams) {
|
||||
struct dwrite_inmemory_stream_data **ptr;
|
||||
|
||||
if (!(ptr = heap_realloc(loader->streams, 2 * loader->capacity * sizeof(*loader->streams))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
loader->streams = ptr;
|
||||
loader->capacity *= 2;
|
||||
}
|
||||
else {
|
||||
loader->capacity = 16;
|
||||
loader->streams = heap_alloc(loader->capacity * sizeof(*loader->streams));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(stream = heap_alloc(sizeof(*stream))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
stream->ref = 1;
|
||||
stream->size = data_size;
|
||||
stream->owner = owner;
|
||||
if (stream->owner) {
|
||||
IUnknown_AddRef(stream->owner);
|
||||
stream->data = (void *)data;
|
||||
}
|
||||
else {
|
||||
if (!(stream->data = heap_alloc(data_size))) {
|
||||
heap_free(stream);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(stream->data, data, data_size);
|
||||
}
|
||||
|
||||
key = loader->filecount;
|
||||
loader->streams[loader->filecount++] = stream;
|
||||
|
||||
return IDWriteFactory_CreateCustomFontFileReference(factory, &key, sizeof(key),
|
||||
(IDWriteFontFileLoader *)&loader->IDWriteInMemoryFontFileLoader_iface, fontfile);
|
||||
}
|
||||
|
||||
static UINT32 WINAPI inmemoryfontfileloader_GetFileCount(IDWriteInMemoryFontFileLoader *iface)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface);
|
||||
|
||||
TRACE("(%p)\n", loader);
|
||||
|
||||
return loader->filecount;
|
||||
}
|
||||
|
||||
static const IDWriteInMemoryFontFileLoaderVtbl inmemoryfontfileloadervtbl =
|
||||
{
|
||||
inmemoryfontfileloader_QueryInterface,
|
||||
inmemoryfontfileloader_AddRef,
|
||||
inmemoryfontfileloader_Release,
|
||||
inmemoryfontfileloader_CreateStreamFromKey,
|
||||
inmemoryfontfileloader_CreateInMemoryFontFileReference,
|
||||
inmemoryfontfileloader_GetFileCount,
|
||||
};
|
||||
|
||||
HRESULT create_inmemory_fileloader(IDWriteFontFileLoader **ret)
|
||||
{
|
||||
struct dwrite_inmemory_fileloader *loader;
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
loader = heap_alloc_zero(sizeof(*loader));
|
||||
if (!loader)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
loader->IDWriteInMemoryFontFileLoader_iface.lpVtbl = &inmemoryfontfileloadervtbl;
|
||||
loader->ref = 1;
|
||||
|
||||
*ret = (IDWriteFontFileLoader *)&loader->IDWriteInMemoryFontFileLoader_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -1617,9 +1617,9 @@ static HRESULT WINAPI dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory
|
|||
{
|
||||
struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
|
||||
|
||||
FIXME("(%p)->(%p): stub\n", This, loader);
|
||||
TRACE("(%p)->(%p)\n", This, loader);
|
||||
|
||||
return E_NOTIMPL;
|
||||
return create_inmemory_fileloader(loader);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory5 *iface, WCHAR const *referrer_url, WCHAR const *extra_headers,
|
||||
|
|
|
@ -7644,14 +7644,15 @@ static void test_inmemory_file_loader(void)
|
|||
IDWriteFontFileLoader *loader, *loader2;
|
||||
IDWriteInMemoryFontFileLoader *inmemory;
|
||||
struct testowner_object ownerobject;
|
||||
const void *key, *data, *frag_start;
|
||||
UINT64 file_size, size, writetime;
|
||||
IDWriteFontFile *file, *file2;
|
||||
IDWriteFontFace *fontface;
|
||||
IDWriteFactory5 *factory5;
|
||||
void *context, *context2;
|
||||
IDWriteFactory *factory;
|
||||
const void *key, *data;
|
||||
UINT32 count, key_size;
|
||||
UINT64 file_size;
|
||||
void *context;
|
||||
DWORD ref_key;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
|
||||
|
@ -7666,15 +7667,9 @@ static void test_inmemory_file_loader(void)
|
|||
|
||||
EXPECT_REF(factory5, 1);
|
||||
hr = IDWriteFactory5_CreateInMemoryFontFileLoader(factory5, &loader);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
EXPECT_REF(factory5, 1);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
IDWriteFactory5_Release(factory5);
|
||||
return;
|
||||
}
|
||||
|
||||
testowner_init(&ownerobject);
|
||||
fontface = create_fontface((IDWriteFactory *)factory5);
|
||||
|
||||
|
@ -7688,6 +7683,9 @@ todo_wine
|
|||
IDWriteFontFileLoader_Release(loader);
|
||||
EXPECT_REF(inmemory, 1);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(!count, "Unexpected file count %u.\n", count);
|
||||
|
||||
/* Use whole font blob to construct in-memory file. */
|
||||
count = 1;
|
||||
hr = IDWriteFontFace_GetFiles(fontface, &count, &file);
|
||||
|
@ -7715,6 +7713,9 @@ todo_wine
|
|||
file_size, NULL, &file);
|
||||
ok(hr == E_INVALIDARG, "got %#x\n", hr);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 1, "Unexpected file count %u.\n", count);
|
||||
|
||||
hr = IDWriteFactory5_RegisterFontFileLoader(factory5, (IDWriteFontFileLoader *)inmemory);
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
EXPECT_REF(inmemory, 2);
|
||||
|
@ -7726,6 +7727,9 @@ todo_wine
|
|||
EXPECT_REF(&ownerobject.IUnknown_iface, 2);
|
||||
EXPECT_REF(inmemory, 3);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 2, "Unexpected file count %u.\n", count);
|
||||
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateInMemoryFontFileReference(inmemory, (IDWriteFactory *)factory5, data,
|
||||
file_size, &ownerobject.IUnknown_iface, &file2);
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
|
@ -7733,6 +7737,9 @@ todo_wine
|
|||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
EXPECT_REF(inmemory, 4);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 3, "Unexpected file count %u.\n", count);
|
||||
|
||||
/* Check in-memory reference key format. */
|
||||
hr = IDWriteFontFile_GetReferenceKey(file, &key, &key_size);
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
|
@ -7762,26 +7769,105 @@ todo_wine
|
|||
|
||||
/* Release file at index 1, create new one to see if index is reused. */
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
IDWriteFontFile_Release(file);
|
||||
ref = IDWriteFontFile_Release(file);
|
||||
ok(ref == 0, "File object not released, %u.\n", ref);
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 3, "Unexpected file count %u.\n", count);
|
||||
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
IDWriteFontFile_Release(file2);
|
||||
ref = IDWriteFontFile_Release(file2);
|
||||
ok(ref == 0, "File object not released, %u.\n", ref);
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 3, "Unexpected file count %u.\n", count);
|
||||
|
||||
hr = IDWriteFactory5_UnregisterFontFileLoader(factory5, (IDWriteFontFileLoader *)inmemory);
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 3);
|
||||
ref = IDWriteInMemoryFontFileLoader_Release(inmemory);
|
||||
ok(ref == 0, "loader not released, %u.\n", ref);
|
||||
EXPECT_REF(&ownerobject.IUnknown_iface, 1);
|
||||
|
||||
/* Test reference key for first added file. */
|
||||
hr = IDWriteFactory5_CreateInMemoryFontFileLoader(factory5, &loader);
|
||||
ok(hr == S_OK, "Failed to create loader, hr %#x.\n", hr);
|
||||
|
||||
hr = IDWriteFontFileLoader_QueryInterface(loader, &IID_IDWriteInMemoryFontFileLoader, (void **)&inmemory);
|
||||
ok(hr == S_OK, "Failed to get in-memory interface, hr %#x.\n", hr);
|
||||
IDWriteFontFileLoader_Release(loader);
|
||||
|
||||
hr = IDWriteFactory5_RegisterFontFileLoader(factory5, (IDWriteFontFileLoader *)inmemory);
|
||||
ok(hr == S_OK, "Failed to register loader, hr %#x.\n", hr);
|
||||
|
||||
ref_key = 0;
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateStreamFromKey(inmemory, &ref_key, sizeof(ref_key), &stream2);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateInMemoryFontFileReference(inmemory, (IDWriteFactory *)factory5, data,
|
||||
file_size, &ownerobject.IUnknown_iface, &file);
|
||||
ok(hr == S_OK, "Failed to create in-memory file reference, hr %#x.\n", hr);
|
||||
|
||||
ref_key = 0;
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateStreamFromKey(inmemory, &ref_key, sizeof(ref_key), &stream2);
|
||||
ok(hr == S_OK, "Failed to create a stream, hr %#x.\n", hr);
|
||||
|
||||
context2 = (void *)0xdeadbeef;
|
||||
hr = IDWriteFontFileStream_ReadFileFragment(stream2, &frag_start, 0, file_size, &context2);
|
||||
ok(hr == S_OK, "Failed to read a fragment, hr %#x.\n", hr);
|
||||
ok(context == NULL, "Unexpected context %p.\n", context2);
|
||||
ok(frag_start == data, "Unexpected fragment pointer %p.\n", frag_start);
|
||||
|
||||
hr = IDWriteFontFileStream_GetFileSize(stream2, &size);
|
||||
ok(hr == S_OK, "Failed to get file size, hr %#x.\n", hr);
|
||||
ok(size == file_size, "Unexpected file size.\n");
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream2, context2);
|
||||
|
||||
writetime = 1;
|
||||
hr = IDWriteFontFileStream_GetLastWriteTime(stream2, &writetime);
|
||||
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
|
||||
ok(writetime == 0, "Unexpected writetime.\n");
|
||||
|
||||
IDWriteFontFileStream_Release(stream2);
|
||||
|
||||
ref_key = 0;
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateStreamFromKey(inmemory, NULL, sizeof(ref_key) - 1, &stream2);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
ref_key = 0;
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateStreamFromKey(inmemory, &ref_key, sizeof(ref_key) - 1, &stream2);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
ref_key = 0;
|
||||
hr = IDWriteInMemoryFontFileLoader_CreateStreamFromKey(inmemory, &ref_key, sizeof(ref_key) + 1, &stream2);
|
||||
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 1, "Unexpected file count %u.\n", count);
|
||||
|
||||
hr = IDWriteFontFile_GetReferenceKey(file, &key, &key_size);
|
||||
ok(hr == S_OK, "Failed to get reference key, hr %#x.\n", hr);
|
||||
|
||||
ok(key && *(DWORD*)key == 0, "Unexpected reference key.\n");
|
||||
ok(key_size == 4, "Unexpected key size %u.\n", key_size);
|
||||
|
||||
IDWriteFontFile_Release(file);
|
||||
|
||||
count = IDWriteInMemoryFontFileLoader_GetFileCount(inmemory);
|
||||
ok(count == 1, "Unexpected file count %u.\n", count);
|
||||
|
||||
hr = IDWriteFactory5_UnregisterFontFileLoader(factory5, (IDWriteFontFileLoader *)inmemory);
|
||||
ok(hr == S_OK, "Failed to unregister loader, hr %#x.\n", hr);
|
||||
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
|
||||
ref = IDWriteFactory5_Release(factory5);
|
||||
ok(ref == 0, "factory not released, %u\n", ref);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue