Module: wine Branch: master Commit: a291a7adf8f92e97e3bb9365008b0fc28d17a773 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a291a7adf8f92e97e3bb936500...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Oct 21 23:20:42 2012 -0400
dwrite: Keep a single instance of system font collection.
---
dlls/dwrite/dwrite_private.h | 3 +- dlls/dwrite/font.c | 97 +++++++++++++++++++++-------------------- dlls/dwrite/main.c | 5 ++- dlls/dwrite/tests/font.c | 12 +++++- 4 files changed, 67 insertions(+), 50 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 4cb0e3b..e9d927a 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 ff4a345..60aa7db 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*)); + + 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 = &This->IDWriteFontCollection_iface; + *collection = system_collection;
return S_OK; } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 4605008..ea1bbce 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 07d3e7d..423c876 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);