From: Aric Stewart Subject: dwrite: Add the system font collection to the dwrite factory object Message-Id: <540145F3.6070508@codeweavers.com> Date: Fri, 29 Aug 2014 22:33:07 -0500 This makes is a properly allocated object --- dlls/dwrite/dwrite_private.h | 1 - dlls/dwrite/font.c | 95 ++++++++++++++++++++------------------------ dlls/dwrite/layout.c | 9 +---- dlls/dwrite/main.c | 28 ++++++++++--- 4 files changed, 68 insertions(+), 65 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 8fda71e..e78f9bf 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -92,7 +92,6 @@ extern HRESULT get_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN; extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; 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; extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 6c3d162..ed056b5 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -127,14 +127,13 @@ typedef struct struct dwrite_fontcollection { IDWriteFontCollection IDWriteFontCollection_iface; + LONG ref; WCHAR **families; UINT32 count; int alloc; }; -static IDWriteFontCollection *system_collection; - struct dwrite_fontfamily { IDWriteFontFamily IDWriteFontFamily_iface; LONG ref; @@ -844,14 +843,30 @@ static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection return E_NOINTERFACE; } -static ULONG WINAPI dwritesysfontcollection_AddRef(IDWriteFontCollection *iface) +static ULONG WINAPI dwritefontcollection_AddRef(IDWriteFontCollection *iface) { - return 2; + struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; } -static ULONG WINAPI dwritesysfontcollection_Release(IDWriteFontCollection *iface) +static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface) { - return 1; + unsigned int i; + struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + + if (!ref) + { + for (i = 0; i < This->count; i++) + heap_free(This->families[i]); + heap_free(This->families); + heap_free(This); + } + + return ref; } static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface) @@ -904,10 +919,10 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec return E_NOTIMPL; } -static const IDWriteFontCollectionVtbl systemfontcollectionvtbl = { +static const IDWriteFontCollectionVtbl fontcollectionvtbl = { dwritefontcollection_QueryInterface, - dwritesysfontcollection_AddRef, - dwritesysfontcollection_Release, + dwritefontcollection_AddRef, + dwritefontcollection_Release, dwritefontcollection_GetFontFamilyCount, dwritefontcollection_GetFontFamily, dwritefontcollection_FindFamilyName, @@ -938,56 +953,34 @@ static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm return add_family_syscollection(collection, lf->lfFaceName) == S_OK; } -static void release_font_collection(IDWriteFontCollection *iface) -{ - struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); - unsigned int i; - - for (i = 0; i < This->count; i++) - heap_free(This->families[i]); - heap_free(This->families); - heap_free(This); -} - -void release_system_fontcollection(void) -{ - if (system_collection) - release_font_collection(system_collection); -} - HRESULT get_system_fontcollection(IDWriteFontCollection **collection) { - if (!system_collection) - { - struct dwrite_fontcollection *This; - LOGFONTW lf; - HDC hdc; - - *collection = NULL; + struct dwrite_fontcollection *This; + LOGFONTW lf; + HDC hdc; - This = heap_alloc(sizeof(struct dwrite_fontcollection)); - if (!This) return E_OUTOFMEMORY; + *collection = NULL; - This->IDWriteFontCollection_iface.lpVtbl = &systemfontcollectionvtbl; - This->alloc = 50; - This->count = 0; - This->families = heap_alloc(This->alloc*sizeof(WCHAR*)); + This = heap_alloc(sizeof(struct dwrite_fontcollection)); + if (!This) return E_OUTOFMEMORY; - TRACE("building system font collection:\n"); + This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl; + This->ref = 1; + This->alloc = 50; + This->count = 0; + This->families = heap_alloc(This->alloc*sizeof(WCHAR*)); - hdc = CreateCompatibleDC(0); - memset(&lf, 0, sizeof(lf)); - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfPitchAndFamily = DEFAULT_PITCH; - lf.lfFaceName[0] = 0; - EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0); - DeleteDC(hdc); + TRACE("building system font collection:\n"); - if (InterlockedCompareExchangePointer((void**)&system_collection, &This->IDWriteFontCollection_iface, NULL)) - release_font_collection(&This->IDWriteFontCollection_iface); - } + hdc = CreateCompatibleDC(0); + memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = DEFAULT_PITCH; + lf.lfFaceName[0] = 0; + EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0); + DeleteDC(hdc); - *collection = system_collection; + *collection = &This->IDWriteFontCollection_iface; return S_OK; } diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index a2da73b..4172d07 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -1781,14 +1781,7 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle IDWriteFontCollection_AddRef(collection); } else - { - HRESULT hr = get_system_fontcollection(&This->format.collection); - if (hr != S_OK) - { - IDWriteTextFormat_Release(&This->IDWriteTextFormat_iface); - return hr; - } - } + ERR("Collection should always be set\n"); *format = &This->IDWriteTextFormat_iface; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 83f705b..01394dc 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -43,10 +43,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; - case DLL_PROCESS_DETACH: - if (reserved) break; - release_system_fontcollection(); - break; } return TRUE; } @@ -364,6 +360,7 @@ struct dwritefactory{ LONG ref; IDWriteLocalFontFileLoader* localfontfileloader; + IDWriteFontCollection *system_collection; IDWriteFontCollectionLoader **loaders; LONG loader_count; @@ -422,6 +419,8 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface) if (This->file_loaders[i]) IDWriteFontFileLoader_Release(This->file_loaders[i]); heap_free(This->file_loaders); + if (This->system_collection) + IDWriteFontCollection_Release(This->system_collection); heap_free(This); } @@ -431,13 +430,22 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface) static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *iface, IDWriteFontCollection **collection, BOOL check_for_updates) { + HRESULT hr = S_OK; struct dwritefactory *This = impl_from_IDWriteFactory(iface); TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates); if (check_for_updates) FIXME("checking for system font updates not implemented\n"); - return get_system_fontcollection(collection); + if (!This->system_collection) + hr = get_system_fontcollection(&This->system_collection); + + if (SUCCEEDED(hr)) + IDWriteFontCollection_AddRef(This->system_collection); + + *collection = This->system_collection; + + return hr; } static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface, @@ -642,6 +650,15 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory *iface, WCHA struct dwritefactory *This = impl_from_IDWriteFactory(iface); TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This, debugstr_w(family_name), collection, weight, style, stretch, size, debugstr_w(locale), format); + + if (!collection) + { + HRESULT hr = IDWriteFactory_GetSystemFontCollection(iface, &collection, FALSE); + if (hr != S_OK) + return hr; + /* Our ref count is 1 too many, since we will add ref in create_textformat */ + IDWriteFontCollection_Release(This->system_collection); + } return create_textformat(family_name, collection, weight, style, stretch, size, locale, format); } @@ -759,6 +776,7 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno This->loaders = heap_alloc_zero(sizeof(*This->loaders) * 2); This->file_loader_count = 2; This->file_loaders = heap_alloc_zero(sizeof(*This->file_loaders) * 2); + This->system_collection = NULL; *factory = (IUnknown*)&This->IDWriteFactory_iface;