dwrite: Use file mapping for local file stream.
This commit is contained in:
parent
c910c8ceed
commit
416527a6ad
|
@ -2042,7 +2042,8 @@ struct dwrite_localfontfilestream
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
struct local_cached_stream *entry;
|
struct local_cached_stream *entry;
|
||||||
HANDLE handle;
|
const void *file_ptr;
|
||||||
|
UINT64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dwrite_localfontfileloader {
|
struct dwrite_localfontfileloader {
|
||||||
|
@ -2100,8 +2101,7 @@ static ULONG WINAPI localfontfilestream_Release(IDWriteFontFileStream *iface)
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
TRACE("(%p)->(%d)\n", This, ref);
|
||||||
|
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
if (This->handle != INVALID_HANDLE_VALUE)
|
UnmapViewOfFile(This->file_ptr);
|
||||||
CloseHandle(This->handle);
|
|
||||||
release_cached_stream(This->entry);
|
release_cached_stream(This->entry);
|
||||||
heap_free(This);
|
heap_free(This);
|
||||||
}
|
}
|
||||||
|
@ -2112,26 +2112,18 @@ static ULONG WINAPI localfontfilestream_Release(IDWriteFontFileStream *iface)
|
||||||
static HRESULT WINAPI localfontfilestream_ReadFileFragment(IDWriteFontFileStream *iface, void const **fragment_start, UINT64 offset, UINT64 fragment_size, void **fragment_context)
|
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);
|
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,
|
TRACE("(%p)->(%p, %s, %s, %p)\n",This, fragment_start,
|
||||||
wine_dbgstr_longlong(offset), wine_dbgstr_longlong(fragment_size), fragment_context);
|
wine_dbgstr_longlong(offset), wine_dbgstr_longlong(fragment_size), fragment_context);
|
||||||
|
|
||||||
*fragment_context = NULL;
|
*fragment_context = NULL;
|
||||||
distance.QuadPart = offset;
|
|
||||||
if (!SetFilePointerEx(This->handle, distance, NULL, FILE_BEGIN))
|
if ((offset >= This->size - 1) || (fragment_size > This->size - offset)) {
|
||||||
return E_FAIL;
|
*fragment_start = NULL;
|
||||||
*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 E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*fragment_start = (char*)This->file_ptr + offset;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2139,16 +2131,13 @@ static void WINAPI localfontfilestream_ReleaseFileFragment(IDWriteFontFileStream
|
||||||
{
|
{
|
||||||
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
|
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
|
||||||
TRACE("(%p)->(%p)\n", This, fragment_context);
|
TRACE("(%p)->(%p)\n", This, fragment_context);
|
||||||
heap_free(fragment_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI localfontfilestream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size)
|
static HRESULT WINAPI localfontfilestream_GetFileSize(IDWriteFontFileStream *iface, UINT64 *size)
|
||||||
{
|
{
|
||||||
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
|
struct dwrite_localfontfilestream *This = impl_from_IDWriteFontFileStream(iface);
|
||||||
LARGE_INTEGER li;
|
TRACE("(%p)->(%p)\n", This, size);
|
||||||
TRACE("(%p)->(%p)\n",This, size);
|
*size = This->size;
|
||||||
GetFileSizeEx(This->handle, &li);
|
|
||||||
*size = li.QuadPart;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2177,15 +2166,17 @@ static const IDWriteFontFileStreamVtbl localfontfilestreamvtbl =
|
||||||
localfontfilestream_GetLastWriteTime
|
localfontfilestream_GetLastWriteTime
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT create_localfontfilestream(HANDLE handle, struct local_cached_stream *entry, IDWriteFontFileStream** iface)
|
static HRESULT create_localfontfilestream(const void *file_ptr, UINT64 size, struct local_cached_stream *entry, IDWriteFontFileStream** iface)
|
||||||
{
|
{
|
||||||
struct dwrite_localfontfilestream *This = heap_alloc(sizeof(struct dwrite_localfontfilestream));
|
struct dwrite_localfontfilestream *This = heap_alloc(sizeof(struct dwrite_localfontfilestream));
|
||||||
if (!This)
|
if (!This)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
This->ref = 1;
|
|
||||||
This->handle = handle;
|
|
||||||
This->IDWriteFontFileStream_iface.lpVtbl = &localfontfilestreamvtbl;
|
This->IDWriteFontFileStream_iface.lpVtbl = &localfontfilestreamvtbl;
|
||||||
|
This->ref = 1;
|
||||||
|
|
||||||
|
This->file_ptr = file_ptr;
|
||||||
|
This->size = size;
|
||||||
This->entry = entry;
|
This->entry = entry;
|
||||||
|
|
||||||
*iface = &This->IDWriteFontFileStream_iface;
|
*iface = &This->IDWriteFontFileStream_iface;
|
||||||
|
@ -2244,11 +2235,12 @@ static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFi
|
||||||
const struct local_refkey *refkey = key;
|
const struct local_refkey *refkey = key;
|
||||||
struct local_cached_stream *stream;
|
struct local_cached_stream *stream;
|
||||||
IDWriteFontFileStream *filestream;
|
IDWriteFontFileStream *filestream;
|
||||||
HANDLE handle;
|
HANDLE file, mapping;
|
||||||
|
LARGE_INTEGER size;
|
||||||
|
void *file_ptr;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p)->(%p, %i, %p)\n", This, key, key_size, ret);
|
TRACE("(%p)->(%p, %i, %p)\n", This, key, key_size, ret);
|
||||||
|
|
||||||
TRACE("name: %s\n", debugstr_w(refkey->name));
|
TRACE("name: %s\n", debugstr_w(refkey->name));
|
||||||
|
|
||||||
/* search cache first */
|
/* search cache first */
|
||||||
|
@ -2262,18 +2254,27 @@ static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFi
|
||||||
|
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
|
|
||||||
handle = CreateFileW(refkey->name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
file = CreateFileW(refkey->name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (file == INVALID_HANDLE_VALUE)
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
GetFileSizeEx(file, &size);
|
||||||
|
mapping = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||||
|
CloseHandle(file);
|
||||||
|
if (!mapping)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
file_ptr = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
CloseHandle(mapping);
|
||||||
|
|
||||||
stream = heap_alloc(sizeof(*stream));
|
stream = heap_alloc(sizeof(*stream));
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
stream->key = heap_alloc(key_size);
|
stream->key = heap_alloc(key_size);
|
||||||
if (!stream->key) {
|
if (!stream->key) {
|
||||||
|
UnmapViewOfFile(file_ptr);
|
||||||
heap_free(stream);
|
heap_free(stream);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
@ -2281,8 +2282,9 @@ static HRESULT WINAPI localfontfileloader_CreateStreamFromKey(IDWriteLocalFontFi
|
||||||
stream->key_size = key_size;
|
stream->key_size = key_size;
|
||||||
memcpy(stream->key, key, key_size);
|
memcpy(stream->key, key, key_size);
|
||||||
|
|
||||||
hr = create_localfontfilestream(handle, stream, &filestream);
|
hr = create_localfontfilestream(file_ptr, size.QuadPart, stream, &filestream);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
UnmapViewOfFile(file_ptr);
|
||||||
heap_free(stream->key);
|
heap_free(stream->key);
|
||||||
heap_free(stream);
|
heap_free(stream);
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -2497,16 +2497,14 @@ static void test_ReadFileFragment(void)
|
||||||
fragment = (void*)0xdeadbeef;
|
fragment = (void*)0xdeadbeef;
|
||||||
context = (void*)0xdeadbeef;
|
context = (void*)0xdeadbeef;
|
||||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment, 0, filesize+1, &context);
|
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment, 0, filesize+1, &context);
|
||||||
todo_wine {
|
|
||||||
ok(hr == E_FAIL, "got 0x%08x\n", hr);
|
ok(hr == E_FAIL, "got 0x%08x\n", hr);
|
||||||
ok(context == NULL, "got %p\n", context);
|
ok(context == NULL, "got %p\n", context);
|
||||||
ok(fragment == NULL, "got %p\n", fragment);
|
ok(fragment == NULL, "got %p\n", fragment);
|
||||||
}
|
|
||||||
fragment = (void*)0xdeadbeef;
|
fragment = (void*)0xdeadbeef;
|
||||||
context = (void*)0xdeadbeef;
|
context = (void*)0xdeadbeef;
|
||||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment, 0, filesize, &context);
|
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment, 0, filesize, &context);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
todo_wine
|
|
||||||
ok(context == NULL, "got %p\n", context);
|
ok(context == NULL, "got %p\n", context);
|
||||||
ok(fragment != NULL, "got %p\n", fragment);
|
ok(fragment != NULL, "got %p\n", fragment);
|
||||||
|
|
||||||
|
@ -2514,13 +2512,21 @@ todo_wine
|
||||||
context2 = (void*)0xdeadbeef;
|
context2 = (void*)0xdeadbeef;
|
||||||
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment2, 0, filesize, &context2);
|
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment2, 0, filesize, &context2);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
todo_wine {
|
|
||||||
ok(context2 == NULL, "got %p\n", context2);
|
ok(context2 == NULL, "got %p\n", context2);
|
||||||
ok(fragment == fragment2, "got %p, %p\n", fragment, fragment2);
|
ok(fragment == fragment2, "got %p, %p\n", fragment, fragment2);
|
||||||
}
|
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context2);
|
IDWriteFontFileStream_ReleaseFileFragment(stream, context2);
|
||||||
|
|
||||||
|
/* fragment is released, try again */
|
||||||
|
fragment = (void*)0xdeadbeef;
|
||||||
|
context = (void*)0xdeadbeef;
|
||||||
|
hr = IDWriteFontFileStream_ReadFileFragment(stream, &fragment, 0, filesize, &context);
|
||||||
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
ok(context == NULL, "got %p\n", context);
|
||||||
|
ok(fragment == fragment2, "got %p, %p\n", fragment, fragment2);
|
||||||
|
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
||||||
|
|
||||||
IDWriteFontFileStream_Release(stream);
|
IDWriteFontFileStream_Release(stream);
|
||||||
IDWriteLocalFontFileLoader_Release(localloader);
|
IDWriteLocalFontFileLoader_Release(localloader);
|
||||||
IDWriteFactory_Release(factory);
|
IDWriteFactory_Release(factory);
|
||||||
|
|
Loading…
Reference in New Issue