dwrite: Implement newer GetSystemFontCollection() variants.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2022-04-25 13:31:49 +03:00 committed by Alexandre Julliard
parent 38d2d2f350
commit fe86eeceeb
4 changed files with 90 additions and 47 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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