diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 4cb0e3beb22..e9d927a1137 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -74,4 +74,5 @@ extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextLayout**) DECLSP extern HRESULT create_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN; extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; -extern HRESULT create_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN; +extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN; +extern void release_system_fontcollection(void) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index ff4a3458ed5..60aa7db3a95 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -129,13 +129,14 @@ 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; @@ -645,32 +646,14 @@ static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection return E_NOINTERFACE; } -static ULONG WINAPI dwritefontcollection_AddRef(IDWriteFontCollection *iface) +static ULONG WINAPI dwritesysfontcollection_AddRef(IDWriteFontCollection *iface) { - struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); - ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p)->(%d)\n", This, ref); - return ref; + return 2; } -static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface) +static ULONG WINAPI dwritesysfontcollection_Release(IDWriteFontCollection *iface) { - struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(%d)\n", This, ref); - - if (!ref) - { - int i; - - for (i = 0; i < This->count; i++) - heap_free(This->families[i]); - heap_free(This->families); - heap_free(This); - } - - return ref; + return 1; } static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface) @@ -715,10 +698,10 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec return E_NOTIMPL; } -static const IDWriteFontCollectionVtbl fontcollectionvtbl = { +static const IDWriteFontCollectionVtbl systemfontcollectionvtbl = { dwritefontcollection_QueryInterface, - dwritefontcollection_AddRef, - dwritefontcollection_Release, + dwritesysfontcollection_AddRef, + dwritesysfontcollection_Release, dwritefontcollection_GetFontFamilyCount, dwritefontcollection_GetFontFamily, dwritefontcollection_FindFamilyName, @@ -749,35 +732,55 @@ static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm return add_family_syscollection(collection, lf->lfFaceName) == S_OK; } -HRESULT create_system_fontcollection(IDWriteFontCollection **collection) +static void release_font_collection(IDWriteFontCollection *iface) { - struct dwrite_fontcollection *This; - LOGFONTW lf; - HDC hdc; + struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); + int i; - *collection = NULL; + for (i = 0; i < This->count; i++) + heap_free(This->families[i]); + heap_free(This->families); + heap_free(This); +} - This = heap_alloc(sizeof(struct dwrite_fontcollection)); - if (!This) return E_OUTOFMEMORY; +void release_system_fontcollection(void) +{ + release_font_collection(system_collection); +} - This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl; - This->ref = 1; +HRESULT get_system_fontcollection(IDWriteFontCollection **collection) +{ + if (!system_collection) + { + struct dwrite_fontcollection *This; + LOGFONTW lf; + HDC hdc; - This->alloc = 50; - This->count = 0; - This->families = heap_alloc(This->alloc*sizeof(WCHAR*)); + *collection = NULL; - TRACE("building system font collection:\n"); + This = heap_alloc(sizeof(struct dwrite_fontcollection)); + if (!This) return E_OUTOFMEMORY; - 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); + This->IDWriteFontCollection_iface.lpVtbl = &systemfontcollectionvtbl; + This->alloc = 50; + This->count = 0; + This->families = heap_alloc(This->alloc*sizeof(WCHAR*)); - *collection = &This->IDWriteFontCollection_iface; + TRACE("building system font collection:\n"); + + 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); + + if (InterlockedCompareExchangePointer((void**)&system_collection, &This->IDWriteFontCollection_iface, NULL)) + release_font_collection(&This->IDWriteFontCollection_iface); + } + + *collection = system_collection; return S_OK; } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 46050082db9..ea1bbcecf7b 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -43,6 +43,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; + case DLL_PROCESS_DETACH: + release_system_fontcollection(); + break; } return TRUE; } @@ -389,7 +392,7 @@ static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *ifac if (check_for_updates) FIXME("checking for system font updates not implemented\n"); - return create_system_fontcollection(collection); + return get_system_fontcollection(collection); } static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 07d3e7d2aef..423c8769e9d 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -525,7 +525,7 @@ todo_wine static void test_system_fontcollection(void) { - IDWriteFontCollection *collection; + IDWriteFontCollection *collection, *coll2; HRESULT hr; UINT32 i; BOOL ret; @@ -533,6 +533,16 @@ static void test_system_fontcollection(void) hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE); ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IDWriteFactory_GetSystemFontCollection(factory, &coll2, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(coll2 == collection, "got %p, was %p\n", coll2, collection); + IDWriteFontCollection_Release(coll2); + + hr = IDWriteFactory_GetSystemFontCollection(factory, &coll2, TRUE); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(coll2 == collection, "got %p, was %p\n", coll2, collection); + IDWriteFontCollection_Release(coll2); + i = IDWriteFontCollection_GetFontFamilyCount(collection); ok(i, "got %u\n", i);