From: Aric Stewart Subject: (resend)[2/5]dwrite: Initial implementation of CreateCustomFontFileReference Message-Id: <53EA66E6.9080604@codeweavers.com> Date: Tue, 12 Aug 2014 14:11:34 -0500 --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 112 +++++++++++++++++++++++++++++++++++++++++++ dlls/dwrite/main.c | 16 ++++++- dlls/dwrite/tests/font.c | 17 +++++++ 4 files changed, 144 insertions(+), 2 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 8db35a3..fcc9b7f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -89,3 +89,4 @@ extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const W extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN; 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; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 0962784..afeca27 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -162,6 +162,15 @@ struct dwrite_fontface { LOGFONTW logfont; }; +struct dwrite_fontfile { + IDWriteFontFile IDWriteFontFile_iface; + LONG ref; + + IDWriteFontFileLoader *loader; + void *reference_key; + UINT32 key_size; +}; + static HRESULT create_fontfamily(const WCHAR *familyname, IDWriteFontFamily **family); static inline struct dwrite_fontface *impl_from_IDWriteFontFace(IDWriteFontFace *iface) @@ -174,6 +183,11 @@ static inline struct dwrite_font *impl_from_IDWriteFont(IDWriteFont *iface) return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont_iface); } +static inline struct dwrite_fontfile *impl_from_IDWriteFontFile(IDWriteFontFile *iface) +{ + return CONTAINING_RECORD(iface, struct dwrite_fontfile, IDWriteFontFile_iface); +} + static inline struct dwrite_fontfamily *impl_from_IDWriteFontFamily(IDWriteFontFamily *iface) { return CONTAINING_RECORD(iface, struct dwrite_fontfamily, IDWriteFontFamily_iface); @@ -978,3 +992,101 @@ HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font) return S_OK; } + +static HRESULT WINAPI dwritefontfile_QueryInterface(IDWriteFontFile *iface, REFIID riid, void **obj) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFile)) + { + *obj = iface; + IDWriteFontFile_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI dwritefontfile_AddRef(IDWriteFontFile *iface) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; +} + +static ULONG WINAPI dwritefontfile_Release(IDWriteFontFile *iface) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(%d)\n", This, ref); + + if (!ref) + { + IDWriteFontFileLoader_Release(This->loader); + heap_free(This->reference_key); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI dwritefontfile_GetReferenceKey(IDWriteFontFile *iface, const void **fontFileReferenceKey, UINT32 *fontFileReferenceKeySize) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + TRACE("(%p)->(%p, %p)\n", This, fontFileReferenceKey, fontFileReferenceKeySize); + *fontFileReferenceKey = This->reference_key; + *fontFileReferenceKeySize = This->key_size; + + return S_OK; +} + +static HRESULT WINAPI dwritefontfile_GetLoader(IDWriteFontFile *iface, IDWriteFontFileLoader **fontFileLoader) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + TRACE("(%p)->(%p)\n", This, fontFileLoader); + *fontFileLoader = This->loader; + IDWriteFontFileLoader_AddRef(This->loader); + + return S_OK; +} + +static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType, DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces) +{ + struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface); + FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This, isSupportedFontType, fontFileType, fontFaceType, numberOfFaces); + return E_NOTIMPL; +} + +static const IDWriteFontFileVtbl dwritefontfilevtbl = { + dwritefontfile_QueryInterface, + dwritefontfile_AddRef, + dwritefontfile_Release, + dwritefontfile_GetReferenceKey, + dwritefontfile_GetLoader, + dwritefontfile_Analyze, +}; + +HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) +{ + struct dwrite_fontfile *This; + + This = heap_alloc(sizeof(struct dwrite_fontfile)); + if (!This) return E_OUTOFMEMORY; + + This->IDWriteFontFile_iface.lpVtbl = &dwritefontfilevtbl; + This->ref = 1; + IDWriteFontFileLoader_AddRef(loader); + This->loader = loader; + This->reference_key = heap_alloc(key_size); + memcpy(This->reference_key, reference_key, key_size); + This->key_size = key_size; + + *font_file = &This->IDWriteFontFile_iface; + + return S_OK; +} diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 3620718..f736301 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -509,9 +509,21 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory *ifac static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory *iface, void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file) { + int i; struct dwritefactory *This = impl_from_IDWriteFactory(iface); - FIXME("(%p)->(%p %u %p %p): stub\n", This, reference_key, key_size, loader, font_file); - return E_NOTIMPL; + HRESULT hr; + + TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file); + + if (loader == NULL) + return E_INVALIDARG; + + for (i = 0; i < This->file_loader_count; i++) + if (This->file_loaders[i] == loader) break; + if (i == This->file_loader_count) + return E_INVALIDARG; + hr = create_font_file(loader, reference_key, key_size, font_file); + return hr; } static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory *iface, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 243af9f..4368bcf 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -761,6 +761,8 @@ static void test_FontLoader(void) { IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl }; IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl }; + IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl }; + IDWriteFontFile *ffile = NULL; HRESULT hr; hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL); @@ -772,6 +774,21 @@ static void test_FontLoader(void) hr = IDWriteFactory_RegisterFontFileLoader(factory, &floader); ok(hr == DWRITE_E_ALREADYREGISTERED, "got 0x%08x\n", hr); + hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &ffile); + ok(hr == S_OK, "got 0x%08x\n", hr); + if (SUCCEEDED(hr)) + IDWriteFontFile_Release(ffile); + + hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader3, &ffile); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + if (SUCCEEDED(hr)) + IDWriteFontFile_Release(ffile); + + hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, NULL, &ffile); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + if (SUCCEEDED(hr)) + IDWriteFontFile_Release(ffile); + hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);