From fe86eeceebf0cc0e39e39102b184e520f2f83279 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 25 Apr 2022 13:31:49 +0300 Subject: [PATCH] dwrite: Implement newer GetSystemFontCollection() variants. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/dwrite_private.h | 4 +- dlls/dwrite/font.c | 28 +++++++--- dlls/dwrite/main.c | 100 +++++++++++++++++++++++------------ dlls/dwrite/tests/font.c | 5 +- 4 files changed, 90 insertions(+), 47 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 60e8b87f499..fdc916adc40 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -299,7 +299,8 @@ extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DEC extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; extern unsigned int get_localizedstrings_count(IDWriteLocalizedStrings *strings) DECLSPEC_HIDDEN; extern BOOL localizedstrings_contains(IDWriteLocalizedStrings *strings, const WCHAR *str) DECLSPEC_HIDDEN; -extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN; +extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection **collection) DECLSPEC_HIDDEN; extern HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN; extern IDWriteTextAnalyzer2 *get_text_analyzer(void) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; @@ -349,6 +350,7 @@ extern HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURI D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) DECLSPEC_HIDDEN; extern HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet *set, DWRITE_FONT_FAMILY_MODEL family_model, REFGUID riid, void **ret) DECLSPEC_HIDDEN; +extern HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) DECLSPEC_HIDDEN; struct dwrite_fontface; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 23dad8970b8..385c7fdeb03 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5092,20 +5092,34 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory7 *factory, IDWri return S_OK; } -HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) +HRESULT get_system_fontcollection(IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection **collection) { IDWriteFontFileEnumerator *enumerator; + IDWriteFontSet *fontset; HRESULT hr; *collection = NULL; - hr = create_system_fontfile_enumerator(factory, &enumerator); - if (FAILED(hr)) - return hr; + if (family_model == DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC) + { + if (SUCCEEDED(hr = create_system_fontset(factory, &IID_IDWriteFontSet, (void **)&fontset))) + { + hr = create_font_collection_from_set(factory, fontset, family_model, + &IID_IDWriteFontCollection, (void **)collection); + IDWriteFontSet_Release(fontset); + } + } + else + { + if (SUCCEEDED(hr = create_system_fontfile_enumerator(factory, &enumerator))) + { + TRACE("Building system font collection for factory %p.\n", factory); + hr = create_font_collection(factory, enumerator, TRUE, (IDWriteFontCollection3 **)collection); + IDWriteFontFileEnumerator_Release(enumerator); + } + } - TRACE("building system font collection for factory %p\n", factory); - hr = create_font_collection(factory, enumerator, TRUE, (IDWriteFontCollection3 **)collection); - IDWriteFontFileEnumerator_Release(enumerator); return hr; } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 4d7d6a7eab0..01b47e673bb 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -598,7 +598,7 @@ struct dwritefactory IDWriteFactory7 IDWriteFactory7_iface; LONG refcount; - IDWriteFontCollection1 *system_collection; + IDWriteFontCollection *system_collections[DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE + 1]; IDWriteFontCollection1 *eudc_collection; IDWriteGdiInterop1 *gdiinterop; IDWriteFontFallback1 *fallback; @@ -640,6 +640,7 @@ static void release_dwritefactory(struct dwritefactory *factory) { struct fileloader *fileloader, *fileloader2; struct collectionloader *loader, *loader2; + unsigned int i; EnterCriticalSection(&factory->cs); release_fontface_cache(&factory->localfontfaces); @@ -654,8 +655,11 @@ static void release_dwritefactory(struct dwritefactory *factory) LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry) release_fileloader(fileloader); - if (factory->system_collection) - IDWriteFontCollection1_Release(factory->system_collection); + for (i = 0; i < ARRAY_SIZE(factory->system_collections); ++i) + { + if (factory->system_collections[i]) + IDWriteFontCollection_Release(factory->system_collections[i]); + } if (factory->eudc_collection) IDWriteFontCollection1_Release(factory->eudc_collection); if (factory->fallback) @@ -703,26 +707,35 @@ static struct collectionloader *factory_get_collection_loader(struct dwritefacto return found; } -static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactory *factory) +static HRESULT factory_get_system_collection(struct dwritefactory *factory, + DWRITE_FONT_FAMILY_MODEL family_model, REFIID riid, void **out) { - IDWriteFontCollection1 *collection; + IDWriteFontCollection *collection; HRESULT hr; - if (factory->system_collection) { - IDWriteFontCollection1_AddRef(factory->system_collection); - return factory->system_collection; + *out = NULL; + + if (family_model != DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC && + family_model != DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE) + { + return E_INVALIDARG; } - if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory7_iface, &collection))) + if (factory->system_collections[family_model]) + return IDWriteFontCollection_QueryInterface(factory->system_collections[family_model], riid, out); + + if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory7_iface, family_model, &collection))) { WARN("Failed to create system font collection, hr %#lx.\n", hr); - return NULL; + return hr; } - if (InterlockedCompareExchangePointer((void **)&factory->system_collection, collection, NULL)) - IDWriteFontCollection1_Release(collection); + if (InterlockedCompareExchangePointer((void **)&factory->system_collections[family_model], collection, NULL)) + IDWriteFontCollection_Release(collection); - return factory->system_collection; + hr = IDWriteFontCollection_QueryInterface(factory->system_collections[family_model], riid, out); + IDWriteFontCollection_Release(factory->system_collections[family_model]); + return hr; } static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory7 *iface, REFIID riid, void **obj) @@ -773,10 +786,17 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory7 *iface) } static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory7 *iface, - IDWriteFontCollection **collection, BOOL check_for_updates) + IDWriteFontCollection **collection, BOOL check_for_updates) { - return IDWriteFactory5_GetSystemFontCollection((IDWriteFactory5 *)iface, FALSE, (IDWriteFontCollection1 **)collection, - check_for_updates); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); + + TRACE("%p, %p, %d.\n", iface, collection, check_for_updates); + + if (check_for_updates) + FIXME("checking for system font updates not implemented\n"); + + return factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection, (void **)collection); } static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory7 *iface, @@ -1167,14 +1187,16 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory7 *iface, WCH TRACE("%p, %s, %p, %d, %d, %d, %.8e, %s, %p.\n", iface, debugstr_w(family_name), collection, weight, style, stretch, size, debugstr_w(locale), format); + *format = NULL; + if (collection) + { IDWriteFontCollection_AddRef(collection); - else { - collection = (IDWriteFontCollection *)factory_get_system_collection(factory); - if (!collection) { - *format = NULL; - return E_FAIL; - } + } + else if (FAILED(hr = factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection, (void **)&collection))) + { + return hr; } hr = create_textformat(family_name, collection, weight, style, stretch, size, locale, format); @@ -1611,7 +1633,7 @@ static int __cdecl create_system_fontset_compare(const void *left, const void *r return wcsicmp(_l, _r); }; -static HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) +HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) { IDWriteFontSetBuilder2 *builder; IDWriteFontSet *fontset; @@ -1691,9 +1713,8 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory7 *if if (check_for_updates) FIXME("checking for system font updates not implemented\n"); - *collection = factory_get_system_collection(factory); - - return *collection ? S_OK : E_FAIL; + return factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection1, (void **)collection); } static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue) @@ -1849,9 +1870,14 @@ static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BO static HRESULT WINAPI dwritefactory6_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection2 **collection) { - FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); - return E_NOTIMPL; + TRACE("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + + if (include_downloadable) + FIXME("remote fonts are not supported\n"); + + return factory_get_system_collection(factory, family_model, &IID_IDWriteFontCollection2, (void **)collection); } static HRESULT WINAPI dwritefactory6_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset, @@ -1893,9 +1919,14 @@ static HRESULT WINAPI dwritefactory7_GetSystemFontSet(IDWriteFactory7 *iface, BO static HRESULT WINAPI dwritefactory7_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection3 **collection) { - FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); - return E_NOTIMPL; + TRACE("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + + if (include_downloadable) + FIXME("remote fonts are not supported\n"); + + return factory_get_system_collection(factory, family_model, &IID_IDWriteFontCollection3, (void **)collection); } static const IDWriteFactory7Vtbl dwritefactoryvtbl = @@ -2040,10 +2071,6 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP &shareddwritefactoryvtbl : &dwritefactoryvtbl; factory->refcount = 1; factory->localfontfileloader = get_local_fontfile_loader(); - factory->system_collection = NULL; - factory->eudc_collection = NULL; - factory->gdiinterop = NULL; - factory->fallback = NULL; list_init(&factory->collection_loaders); list_init(&factory->file_loaders); @@ -2056,7 +2083,10 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP void factory_detach_fontcollection(IDWriteFactory7 *iface, IDWriteFontCollection3 *collection) { struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); - InterlockedCompareExchangePointer((void **)&factory->system_collection, NULL, collection); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(factory->system_collections); ++i) + InterlockedCompareExchangePointer((void **)&factory->system_collections[i], NULL, collection); InterlockedCompareExchangePointer((void **)&factory->eudc_collection, NULL, collection); IDWriteFactory7_Release(iface); } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 2ca1a5f9c81..81008db6f23 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -2654,10 +2654,8 @@ static void test_system_fontcollection(void) hr = IDWriteFactory6_GetSystemFontCollection(factory6, FALSE, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, &collection2); - todo_wine ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { + hr = IDWriteFactory6_GetSystemFontCollection(factory6, FALSE, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, &c2); ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); ok(c2 == collection2 && collection != (IDWriteFontCollection *)c2, "Unexpected collection instance.\n"); @@ -2668,7 +2666,6 @@ static void test_system_fontcollection(void) &collection2); ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); IDWriteFontCollection2_Release(collection2); - } IDWriteFactory6_Release(factory6); } else