Module: wine Branch: master Commit: db9990653c04dda75d0f54cfb4fd46f74ef7359a URL: http://source.winehq.org/git/wine.git/?a=commit;h=db9990653c04dda75d0f54cfb4...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Aug 22 12:42:12 2017 +0300
dwrite: Use safer method to set per-factory system collection reference.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dwrite/main.c | 52 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 18 deletions(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index a13b9fd..3d72a02 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -645,6 +645,27 @@ static struct collectionloader *factory_get_collection_loader(struct dwritefacto return found; }
+static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactory *factory) +{ + IDWriteFontCollection1 *collection; + HRESULT hr; + + if (factory->system_collection) { + IDWriteFontCollection1_AddRef(factory->system_collection); + return factory->system_collection; + } + + if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory5_iface, &collection))) { + WARN("Failed to create system font collection, hr %#x.\n", hr); + return NULL; + } + + if (InterlockedCompareExchangePointer((void **)&factory->system_collection, collection, NULL)) + IDWriteFontCollection1_Release(collection); + + return factory->system_collection; +} + static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory5 *iface, REFIID riid, void **obj) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); @@ -1095,21 +1116,23 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory5 *iface, WCH DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - IDWriteFontCollection *syscollection = NULL; HRESULT hr;
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) { - hr = IDWriteFactory5_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1**)&syscollection, FALSE); - if (FAILED(hr)) - return hr; + if (collection) + IDWriteFontCollection_AddRef(collection); + else { + collection = (IDWriteFontCollection *)factory_get_system_collection(This); + if (!collection) { + *format = NULL; + return E_FAIL; + } }
- hr = create_textformat(family_name, collection ? collection : syscollection, weight, style, stretch, size, locale, format); - if (syscollection) - IDWriteFontCollection_Release(syscollection); + hr = create_textformat(family_name, collection, weight, style, stretch, size, locale, format); + IDWriteFontCollection_Release(collection); return hr; }
@@ -1460,7 +1483,6 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory5 *if IDWriteFontCollection1 **collection, BOOL check_for_updates) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - HRESULT hr = S_OK;
TRACE("(%p)->(%d %p %d)\n", This, include_downloadable, collection, check_for_updates);
@@ -1470,14 +1492,9 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory5 *if if (check_for_updates) FIXME("checking for system font updates not implemented\n");
- if (This->system_collection) - IDWriteFontCollection1_AddRef(This->system_collection); - else - hr = get_system_fontcollection(iface, &This->system_collection); - - *collection = This->system_collection; + *collection = factory_get_system_collection(This);
- return hr; + return *collection ? S_OK : E_FAIL; }
static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory5 *iface, IDWriteFontDownloadQueue **queue) @@ -1783,8 +1800,7 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP void factory_detach_fontcollection(IDWriteFactory5 *iface, IDWriteFontCollection1 *collection) { struct dwritefactory *factory = impl_from_IDWriteFactory5(iface); - if (factory->system_collection == collection) - factory->system_collection = NULL; + InterlockedCompareExchangePointer((void **)&factory->system_collection, NULL, collection); if (factory->eudc_collection == collection) factory->eudc_collection = NULL; IDWriteFactory5_Release(iface);