dwrite: Keep a single instance of system font collection.
This commit is contained in:
parent
7978a38f24
commit
a291a7adf8
|
@ -74,4 +74,5 @@ extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextLayout**) DECLSP
|
||||||
extern HRESULT create_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN;
|
extern HRESULT create_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) 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;
|
||||||
|
|
|
@ -129,13 +129,14 @@ typedef struct
|
||||||
|
|
||||||
struct dwrite_fontcollection {
|
struct dwrite_fontcollection {
|
||||||
IDWriteFontCollection IDWriteFontCollection_iface;
|
IDWriteFontCollection IDWriteFontCollection_iface;
|
||||||
LONG ref;
|
|
||||||
|
|
||||||
WCHAR **families;
|
WCHAR **families;
|
||||||
UINT32 count;
|
UINT32 count;
|
||||||
int alloc;
|
int alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static IDWriteFontCollection *system_collection;
|
||||||
|
|
||||||
struct dwrite_fontfamily {
|
struct dwrite_fontfamily {
|
||||||
IDWriteFontFamily IDWriteFontFamily_iface;
|
IDWriteFontFamily IDWriteFontFamily_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
@ -645,32 +646,14 @@ static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection
|
||||||
return E_NOINTERFACE;
|
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);
|
return 2;
|
||||||
ULONG ref = InterlockedIncrement(&This->ref);
|
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
|
||||||
return ref;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface)
|
static ULONG WINAPI dwritesysfontcollection_Release(IDWriteFontCollection *iface)
|
||||||
{
|
{
|
||||||
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
|
return 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface)
|
static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface)
|
||||||
|
@ -715,10 +698,10 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IDWriteFontCollectionVtbl fontcollectionvtbl = {
|
static const IDWriteFontCollectionVtbl systemfontcollectionvtbl = {
|
||||||
dwritefontcollection_QueryInterface,
|
dwritefontcollection_QueryInterface,
|
||||||
dwritefontcollection_AddRef,
|
dwritesysfontcollection_AddRef,
|
||||||
dwritefontcollection_Release,
|
dwritesysfontcollection_Release,
|
||||||
dwritefontcollection_GetFontFamilyCount,
|
dwritefontcollection_GetFontFamilyCount,
|
||||||
dwritefontcollection_GetFontFamily,
|
dwritefontcollection_GetFontFamily,
|
||||||
dwritefontcollection_FindFamilyName,
|
dwritefontcollection_FindFamilyName,
|
||||||
|
@ -749,8 +732,26 @@ static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm
|
||||||
return add_family_syscollection(collection, lf->lfFaceName) == S_OK;
|
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 = impl_from_IDWriteFontCollection(iface);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
release_font_collection(system_collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT get_system_fontcollection(IDWriteFontCollection **collection)
|
||||||
|
{
|
||||||
|
if (!system_collection)
|
||||||
|
{
|
||||||
struct dwrite_fontcollection *This;
|
struct dwrite_fontcollection *This;
|
||||||
LOGFONTW lf;
|
LOGFONTW lf;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
@ -760,9 +761,7 @@ HRESULT create_system_fontcollection(IDWriteFontCollection **collection)
|
||||||
This = heap_alloc(sizeof(struct dwrite_fontcollection));
|
This = heap_alloc(sizeof(struct dwrite_fontcollection));
|
||||||
if (!This) return E_OUTOFMEMORY;
|
if (!This) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl;
|
This->IDWriteFontCollection_iface.lpVtbl = &systemfontcollectionvtbl;
|
||||||
This->ref = 1;
|
|
||||||
|
|
||||||
This->alloc = 50;
|
This->alloc = 50;
|
||||||
This->count = 0;
|
This->count = 0;
|
||||||
This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
|
This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
|
||||||
|
@ -777,7 +776,11 @@ HRESULT create_system_fontcollection(IDWriteFontCollection **collection)
|
||||||
EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0);
|
EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0);
|
||||||
DeleteDC(hdc);
|
DeleteDC(hdc);
|
||||||
|
|
||||||
*collection = &This->IDWriteFontCollection_iface;
|
if (InterlockedCompareExchangePointer((void**)&system_collection, &This->IDWriteFontCollection_iface, NULL))
|
||||||
|
release_font_collection(&This->IDWriteFontCollection_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
*collection = system_collection;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,9 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls( hinstDLL );
|
DisableThreadLibraryCalls( hinstDLL );
|
||||||
break;
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
release_system_fontcollection();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -389,7 +392,7 @@ static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *ifac
|
||||||
if (check_for_updates)
|
if (check_for_updates)
|
||||||
FIXME("checking for system font updates not implemented\n");
|
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,
|
static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface,
|
||||||
|
|
|
@ -525,7 +525,7 @@ todo_wine
|
||||||
|
|
||||||
static void test_system_fontcollection(void)
|
static void test_system_fontcollection(void)
|
||||||
{
|
{
|
||||||
IDWriteFontCollection *collection;
|
IDWriteFontCollection *collection, *coll2;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -533,6 +533,16 @@ static void test_system_fontcollection(void)
|
||||||
hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
|
hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
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);
|
i = IDWriteFontCollection_GetFontFamilyCount(collection);
|
||||||
ok(i, "got %u\n", i);
|
ok(i, "got %u\n", i);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue