Nikolay Sivov : dwrite: Keep a single instance of system font collection.
Alexandre Julliard
julliard at winehq.org
Tue Oct 23 13:37:18 CDT 2012
Module: wine
Branch: master
Commit: a291a7adf8f92e97e3bb9365008b0fc28d17a773
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a291a7adf8f92e97e3bb9365008b0fc28d17a773
Author: Nikolay Sivov <nsivov at 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);
More information about the wine-cvs
mailing list