mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 12:47:44 +00:00
dwrite: Beginning implementation of IDWriteLocalFontFileLoader.
This commit is contained in:
parent
78e02675ab
commit
95466a1c2f
4 changed files with 307 additions and 2 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue