From fd06cc7c492c20233056dc33f91c253f793802fe Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 20 Apr 2016 10:51:01 +0300 Subject: [PATCH] dwrite: Initial implementation of IDWriteFontFaceReference. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/dwrite_private.h | 2 + dlls/dwrite/font.c | 263 +++++++++++++++++++++++++++++++++++ dlls/dwrite/main.c | 18 ++- dlls/dwrite/tests/font.c | 13 +- 4 files changed, 285 insertions(+), 11 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 03a31b07d82..69bd6d14ddd 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -147,6 +147,8 @@ extern HRESULT create_system_fontfallback(IDWriteFactory3*,IDWriteFontFallback** extern void release_system_fontfallback(IDWriteFontFallback*) DECLSPEC_HIDDEN; extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, IDWriteFont**) DECLSPEC_HIDDEN; +extern HRESULT create_fontfacereference(IDWriteFactory3*,IDWriteFontFile*,UINT32,DWRITE_FONT_SIMULATIONS, + IDWriteFontFaceReference**) DECLSPEC_HIDDEN; /* Opentype font table functions */ struct dwrite_font_props { diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 4d5f43c0f50..597fb973dc5 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -242,6 +242,16 @@ struct dwrite_fontfile { IDWriteFontFileStream *stream; }; +struct dwrite_fontfacereference { + IDWriteFontFaceReference IDWriteFontFaceReference_iface; + LONG ref; + + IDWriteFontFile *file; + UINT32 index; + USHORT simulations; + IDWriteFactory3 *factory; +}; + static inline struct dwrite_fontface *impl_from_IDWriteFontFace3(IDWriteFontFace3 *iface) { return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace3_iface); @@ -282,6 +292,11 @@ static inline struct dwrite_fontlist *impl_from_IDWriteFontList1(IDWriteFontList return CONTAINING_RECORD(iface, struct dwrite_fontlist, IDWriteFontList1_iface); } +static inline struct dwrite_fontfacereference *impl_from_IDWriteFontFaceReference(IDWriteFontFaceReference *iface) +{ + return CONTAINING_RECORD(iface, struct dwrite_fontfacereference, IDWriteFontFaceReference_iface); +} + static inline const char *debugstr_tag(UINT32 tag) { return debugstr_an((char*)&tag, 4); @@ -5294,3 +5309,251 @@ failed: IDWriteFontFace3_Release(fontface3); return hr; } + +/* IDWriteFontFaceReference */ +static HRESULT WINAPI fontfacereference_QueryInterface(IDWriteFontFaceReference *iface, REFIID riid, void **obj) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IDWriteFontFaceReference) || IsEqualIID(riid, &IID_IUnknown)) { + *obj = iface; + IDWriteFontFaceReference_AddRef(iface); + return S_OK; + } + + *obj = NULL; + + return E_NOINTERFACE; +} + +static ULONG WINAPI fontfacereference_AddRef(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%u)\n", This, ref); + return ref; +} + +static ULONG WINAPI fontfacereference_Release(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(%u)\n", This, ref); + + if (!ref) { + IDWriteFontFile_Release(This->file); + IDWriteFactory3_Release(This->factory); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI fontfacereference_CreateFontFace(IDWriteFontFaceReference *iface, IDWriteFontFace3 **fontface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + TRACE("(%p)->(%p)\n", This, fontface); + + return IDWriteFontFaceReference_CreateFontFaceWithSimulations(iface, This->simulations, fontface); +} + +static HRESULT WINAPI fontfacereference_CreateFontFaceWithSimulations(IDWriteFontFaceReference *iface, + DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace3 **ret) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + DWRITE_FONT_FILE_TYPE file_type; + DWRITE_FONT_FACE_TYPE face_type; + IDWriteFontFace *fontface; + BOOL is_supported; + UINT32 face_num; + HRESULT hr; + + TRACE("(%p)->(%d %p)\n", This, simulations, ret); + + hr = IDWriteFontFile_Analyze(This->file, &is_supported, &file_type, &face_type, &face_num); + if (FAILED(hr)) + return hr; + + hr = IDWriteFactory3_CreateFontFace(This->factory, face_type, 1, &This->file, This->index, simulations, &fontface); + if (SUCCEEDED(hr)) { + hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)ret); + IDWriteFontFace_Release(fontface); + } + + return hr; +} + +static BOOL WINAPI fontfacereference_Equals(IDWriteFontFaceReference *iface, IDWriteFontFaceReference *ref) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p)->(%p): stub\n", This, ref); + + return E_NOTIMPL; +} + +static UINT32 WINAPI fontfacereference_GetFontFaceIndex(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + TRACE("(%p)\n", This); + + return This->index; +} + +static DWRITE_FONT_SIMULATIONS WINAPI fontfacereference_GetSimulations(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + TRACE("(%p)\n", This); + + return This->simulations; +} + +static HRESULT WINAPI fontfacereference_GetFontFile(IDWriteFontFaceReference *iface, IDWriteFontFile **file) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + IDWriteFontFileLoader *loader; + const void *key; + UINT32 key_size; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, file); + + hr = IDWriteFontFile_GetReferenceKey(This->file, &key, &key_size); + if (FAILED(hr)) + return hr; + + hr = IDWriteFontFile_GetLoader(This->file, &loader); + if (FAILED(hr)) + return hr; + + hr = IDWriteFactory3_CreateCustomFontFileReference(This->factory, key, key_size, loader, file); + IDWriteFontFileLoader_Release(loader); + + return hr; +} + +static UINT64 WINAPI fontfacereference_GetLocalFileSize(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p): stub\n", This); + + return 0; +} + +static UINT64 WINAPI fontfacereference_GetFileSize(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p): stub\n", This); + + return 0; +} + +static HRESULT WINAPI fontfacereference_GetFileTime(IDWriteFontFaceReference *iface, FILETIME *writetime) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p)->(%p): stub\n", This, writetime); + + return E_NOTIMPL; +} + +static DWRITE_LOCALITY WINAPI fontfacereference_GetLocality(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p): stub\n", This); + + return DWRITE_LOCALITY_LOCAL; +} + +static HRESULT WINAPI fontfacereference_EnqueueFontDownloadRequest(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p): stub\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI fontfacereference_EnqueueCharacterDownloadRequest(IDWriteFontFaceReference *iface, WCHAR const *chars, + UINT32 count) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p)->(%s:%u): stub\n", This, debugstr_wn(chars, count), count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI fontfacereference_EnqueueGlyphDownloadRequest(IDWriteFontFaceReference *iface, UINT16 const *glyphs, + UINT32 count) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p)->(%p %u): stub\n", This, glyphs, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI fontfacereference_EnqueueFileFragmentDownloadRequest(IDWriteFontFaceReference *iface, + UINT64 offset, UINT64 size) +{ + struct dwrite_fontfacereference *This = impl_from_IDWriteFontFaceReference(iface); + + FIXME("(%p)->(%s %s): stub\n", This, wine_dbgstr_longlong(offset), wine_dbgstr_longlong(size)); + + return E_NOTIMPL; +} + +static const IDWriteFontFaceReferenceVtbl fontfacereferencevtbl = { + fontfacereference_QueryInterface, + fontfacereference_AddRef, + fontfacereference_Release, + fontfacereference_CreateFontFace, + fontfacereference_CreateFontFaceWithSimulations, + fontfacereference_Equals, + fontfacereference_GetFontFaceIndex, + fontfacereference_GetSimulations, + fontfacereference_GetFontFile, + fontfacereference_GetLocalFileSize, + fontfacereference_GetFileSize, + fontfacereference_GetFileTime, + fontfacereference_GetLocality, + fontfacereference_EnqueueFontDownloadRequest, + fontfacereference_EnqueueCharacterDownloadRequest, + fontfacereference_EnqueueGlyphDownloadRequest, + fontfacereference_EnqueueFileFragmentDownloadRequest +}; + +HRESULT create_fontfacereference(IDWriteFactory3 *factory, IDWriteFontFile *file, UINT32 index, + DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **ret) +{ + struct dwrite_fontfacereference *ref; + + *ret = NULL; + + ref = heap_alloc(sizeof(*ref)); + if (!ref) + return E_OUTOFMEMORY; + + ref->IDWriteFontFaceReference_iface.lpVtbl = &fontfacereferencevtbl; + ref->ref = 1; + + ref->factory = factory; + IDWriteFactory3_AddRef(ref->factory); + ref->file = file; + IDWriteFontFile_AddRef(ref->file); + ref->index = index; + ref->simulations = simulations; + *ret = &ref->IDWriteFontFaceReference_iface; + + return S_OK; +} diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 8b87590e901..dd66d8d433a 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1270,19 +1270,29 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory3 *i { struct dwritefactory *This = impl_from_IDWriteFactory3(iface); - FIXME("(%p)->(%p %u %x %p): stub\n", This, file, index, simulations, reference); + TRACE("(%p)->(%p %u %x %p)\n", This, file, index, simulations, reference); - return E_NOTIMPL; + return create_fontfacereference(iface, file, index, simulations, reference); } static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory3 *iface, WCHAR const *path, FILETIME const *writetime, UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference) { struct dwritefactory *This = impl_from_IDWriteFactory3(iface); + IDWriteFontFile *file; + HRESULT hr; - FIXME("(%p)->(%s %p %u %x, %p): stub\n", This, debugstr_w(path), writetime, index, simulations, reference); + TRACE("(%p)->(%s %p %u %x, %p)\n", This, debugstr_w(path), writetime, index, simulations, reference); - return E_NOTIMPL; + hr = IDWriteFactory3_CreateFontFileReference(iface, path, writetime, &file); + if (FAILED(hr)) { + *reference = NULL; + return hr; + } + + hr = IDWriteFactory3_CreateFontFaceReference_(iface, file, index, simulations, reference); + IDWriteFontFile_Release(file); + return hr; } static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory3 *iface, IDWriteFontSet **fontset) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 54f0714ea5f..f8f878c7ce8 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -5847,14 +5847,12 @@ static void test_CreateFontFaceReference(void) path = create_testfontfile(test_fontfile); hr = IDWriteFactory3_CreateFontFaceReference(factory3, NULL, NULL, 0, DWRITE_FONT_SIMULATIONS_NONE, &ref); -todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); /* test file is not a collection, but reference could still be created */ hr = IDWriteFactory3_CreateFontFaceReference(factory3, path, NULL, 1, DWRITE_FONT_SIMULATIONS_NONE, &ref); -todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -if (hr == S_OK) { + index = IDWriteFontFaceReference_GetFontFaceIndex(ref); ok(index == 1, "got %u\n", index); @@ -5863,20 +5861,21 @@ if (hr == S_OK) { IDWriteFontFile_Release(file); hr = IDWriteFontFaceReference_CreateFontFace(ref, &fontface); +todo_wine ok(hr == DWRITE_E_FILEFORMAT, "got 0x%08x\n", hr); IDWriteFontFaceReference_Release(ref); -} + /* path however has to be valid */ hr = IDWriteFactory3_CreateFontFaceReference(factory3, dummyW, NULL, 0, DWRITE_FONT_SIMULATIONS_NONE, &ref); todo_wine ok(hr == DWRITE_E_FILENOTFOUND, "got 0x%08x\n", hr); + if (hr == S_OK) + IDWriteFontFaceReference_Release(ref); EXPECT_REF(factory3, 1); hr = IDWriteFactory3_CreateFontFaceReference(factory3, path, NULL, 0, DWRITE_FONT_SIMULATIONS_NONE, &ref); -todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); -if (hr == S_OK) { EXPECT_REF(factory3, 2); /* new file is returned */ @@ -5922,7 +5921,7 @@ if (hr == S_OK) { IDWriteFontFaceReference_Release(ref); IDWriteFontFile_Release(file); IDWriteFontFile_Release(file1); -} + IDWriteFactory3_Release(factory3); DELETE_FONTFILE(path); }