-- v2: dwrite: Reuse font set entries to return set instances for collections. dwrite/tests: Add a small test for EUDC collection. dwrite: Cache set elements for returned system sets. dwrite: Remove nested structures in fontset entries. dwrite: Simplify collection initialization helper. dwrite: Create custom collections using font sets. dwrite: Create both WWS and typographic system collections using system font set. dwrite: Mark system font sets. dwrite: Remove system collection marker. dwrite: Check against local file loader in ConvertFontToLOGFONT(). dwrite/tests: Add some more tests for ConvertFontToLOGFONT().
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/tests/font.c | 100 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 3 deletions(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index f277134bc0d..08846e4b5a7 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -3042,9 +3042,11 @@ static void test_CustomFontCollection(void) IDWriteFontFile *fontfile, *fontfile2; IDWriteLocalizedStrings *string; IDWriteFont *idfont, *idfont2; + IDWriteGdiInterop *interop; IDWriteFactory *factory; UINT32 index, count; - BOOL exists; + BOOL system, exists; + LOGFONTW logfont; HRESULT hr; HRSRC font; ULONG ref; @@ -3133,6 +3135,19 @@ static void test_CustomFontCollection(void)
hr = IDWriteFontFamily_GetFont(family, 0, &idfont); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* Font created using a custom loader */ + hr = IDWriteFactory_GetGdiInterop(factory, &interop); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + system = TRUE; + memset(&logfont, 0, sizeof(logfont)); + hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, idfont, &logfont, &system); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!system, "Unexpected flag %d.\n", system); + + IDWriteGdiInterop_Release(interop); + EXPECT_REF(idfont, 1); EXPECT_REF(family, 2); hr = IDWriteFontFamily_GetFont(family, 0, &idfont2); @@ -4767,6 +4782,7 @@ static void test_ConvertFontToLOGFONT(void) IDWriteFontCollection *collection; IDWriteGdiInterop *interop; IDWriteFontFamily *family; + IDWriteFactory3 *factory3; IDWriteFont *font; LOGFONTW logfont; UINT32 i, count; @@ -4804,6 +4820,9 @@ if (0) { /* crashes on native */ ok(!system, "got %d\n", system); ok(logfont.lfFaceName[0] == 0, "got face name %s\n", wine_dbgstr_w(logfont.lfFaceName));
+ IDWriteFontFamily_Release(family); + IDWriteFont_Release(font); + count = IDWriteFontCollection_GetFontFamilyCount(collection); for (i = 0; i < count; i++) { WCHAR nameW[128], familynameW[64], facenameW[64]; @@ -4892,9 +4911,84 @@ if (0) { /* crashes on native */
IDWriteFactory_Release(factory2);
+ if (SUCCEEDED(IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory3, (void **)&factory3))) + { + IDWriteFontCollection1 *collection2; + IDWriteFontSet *fontset, *fontset2; + IDWriteFontSetBuilder2 *builder2; + IDWriteFontSetBuilder *builder; + WCHAR *path; + + /* System font set -> collection -> ConvertFontToLOGFONT() */ + hr = IDWriteFactory3_GetSystemFontSet(factory3, &fontset); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFactory3_CreateFontCollectionFromFontSet(factory3, fontset, &collection2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFontCollection1_GetFontFamily(collection2, 0, (IDWriteFontFamily1 **)&family); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFontFamily_GetFont(family, 0, &font); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + system = FALSE; + memset(&logfont, 0, sizeof(logfont)); + hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(system, "Unexpected flag %d.\n", system); + + IDWriteFont_Release(font); + IDWriteFontSet_Release(fontset); + IDWriteFontFamily_Release(family); + IDWriteFontCollection1_Release(collection2); + + /* User font set using local file -> custom collection -> ConvertFontToLOGFONT() */ + hr = IDWriteFactory3_CreateFontSetBuilder(factory3, &builder); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + if (SUCCEEDED(IDWriteFontSetBuilder_QueryInterface(builder, &IID_IDWriteFontSetBuilder2, (void **)&builder2))) + { + path = create_testfontfile(test_fontfile); + + hr = IDWriteFontSetBuilder2_AddFontFile(builder2, path); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFontSetBuilder_CreateFontSet(builder, &fontset2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFactory3_CreateFontCollectionFromFontSet(factory3, fontset2, &collection2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFontCollection1_GetFontFamily(collection2, 0, (IDWriteFontFamily1 **)&family); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IDWriteFontFamily_GetFont(family, 0, &font); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + system = FALSE; + memset(&logfont, 0, sizeof(logfont)); + hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(system, "Unexpected flag %d.\n", system); + + IDWriteFont_Release(font); + IDWriteFontSet_Release(fontset2); + IDWriteFontFamily_Release(family); + IDWriteFontCollection1_Release(collection2); + + IDWriteFontSetBuilder2_Release(builder2); + DeleteFileW(path); + } + + IDWriteFontSetBuilder_Release(builder); + + IDWriteFactory3_Release(factory3); + } + IDWriteFontCollection_Release(collection); - IDWriteFontFamily_Release(family); - IDWriteFont_Release(font); IDWriteGdiInterop_Release(interop); ref = IDWriteFactory_Release(factory); ok(ref == 0, "factory not released, %lu\n", ref);
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 14 ++++++++++++++ dlls/dwrite/gdiinterop.c | 20 ++++++++------------ dlls/dwrite/tests/font.c | 2 -- 4 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index b200ce58eb6..7fd0cdbe13f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -365,6 +365,7 @@ extern void factory_detach_fontcollection(IDWriteFactory7 *factory, IDWriteFontC extern void factory_detach_gdiinterop(IDWriteFactory7 *factory, IDWriteGdiInterop1 *interop); extern struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *factory, struct list *fontfaces, IDWriteFontFace5 *fontface); +extern IDWriteFontFile *get_fontfile_from_font(IDWriteFont *font); extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*); extern void get_logfont_from_fontface(IDWriteFontFace*,LOGFONTW*); extern HRESULT get_fontsig_from_font(IDWriteFont*,FONTSIGNATURE*); diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 65bf7021938..316d3eea1c7 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -2599,6 +2599,20 @@ static HRESULT create_font(struct dwrite_fontfamily *family, UINT32 index, IDWri return S_OK; }
+IDWriteFontFile *get_fontfile_from_font(IDWriteFont *font_iface) +{ + struct dwrite_font *font = unsafe_impl_from_IDWriteFont(font_iface); + IDWriteFontFile *file = NULL; + + if (font) + { + file = font->data->file; + IDWriteFontFile_AddRef(file); + } + + return file; +} + /* IDWriteFontList2 */ static HRESULT WINAPI dwritefontlist_QueryInterface(IDWriteFontList2 *iface, REFIID riid, void **obj) { diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c index 3e456a04a41..7f4b7f7689b 100644 --- a/dlls/dwrite/gdiinterop.c +++ b/dlls/dwrite/gdiinterop.c @@ -693,8 +693,8 @@ static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop1 *iface static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop1 *iface, IDWriteFont *font, LOGFONTW *logfont, BOOL *is_systemfont) { - IDWriteFontCollection *collection; - IDWriteFontFamily *family; + IDWriteFontFileLoader *loader; + IDWriteFontFile *file; HRESULT hr;
TRACE("%p, %p, %p, %p.\n", iface, font, logfont, is_systemfont); @@ -703,20 +703,16 @@ static HRESULT WINAPI gdiinterop_ConvertFontToLOGFONT(IDWriteGdiInterop1 *iface,
memset(logfont, 0, sizeof(*logfont));
- if (!font) - return E_INVALIDARG; + file = get_fontfile_from_font(font);
- hr = IDWriteFont_GetFontFamily(font, &family); - if (FAILED(hr)) - return hr; + if (!font || !file) + return E_INVALIDARG;
- hr = IDWriteFontFamily_GetFontCollection(family, &collection); - IDWriteFontFamily_Release(family); - if (FAILED(hr)) + if (FAILED(hr = IDWriteFontFile_GetLoader(file, &loader))) return hr;
- *is_systemfont = is_system_collection(collection); - IDWriteFontCollection_Release(collection); + *is_systemfont = loader == get_local_fontfile_loader(); + IDWriteFontFileLoader_Release(loader);
get_logfont_from_font(font, logfont); logfont->lfCharSet = DEFAULT_CHARSET; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 08846e4b5a7..9d31407cf94 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -4936,7 +4936,6 @@ if (0) { /* crashes on native */ memset(&logfont, 0, sizeof(logfont)); hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(system, "Unexpected flag %d.\n", system);
IDWriteFont_Release(font); @@ -4971,7 +4970,6 @@ if (0) { /* crashes on native */ memset(&logfont, 0, sizeof(logfont)); hr = IDWriteGdiInterop_ConvertFontToLOGFONT(interop, font, &logfont, &system); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(system, "Unexpected flag %d.\n", system);
IDWriteFont_Release(font);
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/dwrite_private.h | 1 - dlls/dwrite/font.c | 63 +++--------------------------------- 2 files changed, 5 insertions(+), 59 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 7fd0cdbe13f..688ac2d12f6 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -341,7 +341,6 @@ extern HRESULT create_fontface(const struct fontface_desc *desc, struct list *ca extern HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, IDWriteFontCollection3 **collection); extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**); -extern BOOL is_system_collection(IDWriteFontCollection*); extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*); extern HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**); extern BOOL is_face_type_supported(DWRITE_FONT_FACE_TYPE); diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 316d3eea1c7..4eb9961d8df 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -40,8 +40,6 @@ WINE_DECLARE_DEBUG_CHANNEL(dwrite_file); #define MS_CPAL_TAG DWRITE_MAKE_OPENTYPE_TAG('C','P','A','L') #define MS_COLR_TAG DWRITE_MAKE_OPENTYPE_TAG('C','O','L','R')
-static const IID IID_issystemcollection = {0x14d88047,0x331f,0x4cd3,{0xbc,0xa8,0x3e,0x67,0x99,0xaf,0x34,0x75}}; - static const FLOAT RECOMMENDED_OUTLINE_AA_THRESHOLD = 100.0f; static const FLOAT RECOMMENDED_OUTLINE_A_THRESHOLD = 350.0f; static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f; @@ -3212,39 +3210,6 @@ static HRESULT create_fontfamily(struct dwrite_fontcollection *collection, UINT3 return S_OK; }
-BOOL is_system_collection(IDWriteFontCollection *collection) -{ - void *obj; - return IDWriteFontCollection_QueryInterface(collection, &IID_issystemcollection, &obj) == S_OK; -} - -static HRESULT WINAPI dwritesystemfontcollection_QueryInterface(IDWriteFontCollection3 *iface, REFIID riid, void **obj) -{ - struct dwrite_fontcollection *collection = impl_from_IDWriteFontCollection3(iface); - - TRACE("%p, %s, %p.\n", collection, debugstr_guid(riid), obj); - - if (IsEqualIID(riid, &IID_IDWriteFontCollection3) || - IsEqualIID(riid, &IID_IDWriteFontCollection2) || - IsEqualIID(riid, &IID_IDWriteFontCollection1) || - IsEqualIID(riid, &IID_IDWriteFontCollection) || - IsEqualIID(riid, &IID_IUnknown)) - { - *obj = iface; - IDWriteFontCollection3_AddRef(iface); - return S_OK; - } - - *obj = NULL; - - if (IsEqualIID(riid, &IID_issystemcollection)) - return S_OK; - - WARN("%s not implemented.\n", debugstr_guid(riid)); - - return E_NOINTERFACE; -} - static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection3 *iface, REFIID riid, void **obj) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); @@ -3542,24 +3507,6 @@ static const IDWriteFontCollection3Vtbl fontcollectionvtbl = dwritefontcollection3_GetExpirationEvent, };
-static const IDWriteFontCollection3Vtbl systemfontcollectionvtbl = -{ - dwritesystemfontcollection_QueryInterface, - dwritefontcollection_AddRef, - dwritefontcollection_Release, - dwritefontcollection_GetFontFamilyCount, - dwritefontcollection_GetFontFamily, - dwritefontcollection_FindFamilyName, - dwritefontcollection_GetFontFromFontFace, - dwritefontcollection1_GetFontSet, - dwritefontcollection1_GetFontFamily, - dwritefontcollection2_GetFontFamily, - dwritefontcollection2_GetMatchingFonts, - dwritefontcollection2_GetFontFamilyModel, - dwritefontcollection2_GetFontSet, - dwritefontcollection3_GetExpirationEvent, -}; - static HRESULT fontfamily_add_font(struct dwrite_fontfamily_data *family_data, struct dwrite_font_data *font_data) { if (!dwrite_array_reserve((void **)&family_data->fonts, &family_data->size, family_data->count + 1, @@ -3592,9 +3539,9 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio }
static HRESULT init_font_collection(struct dwrite_fontcollection *collection, IDWriteFactory7 *factory, - DWRITE_FONT_FAMILY_MODEL family_model, BOOL is_system) + DWRITE_FONT_FAMILY_MODEL family_model) { - collection->IDWriteFontCollection3_iface.lpVtbl = is_system ? &systemfontcollectionvtbl : &fontcollectionvtbl; + collection->IDWriteFontCollection3_iface.lpVtbl = &fontcollectionvtbl; collection->refcount = 1; collection->factory = factory; IDWriteFactory7_AddRef(collection->factory); @@ -4708,7 +4655,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, is_system); + hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); if (FAILED(hr)) { free(collection); @@ -4910,7 +4857,7 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- if (FAILED(hr = init_font_collection(collection, factory, family_model, FALSE))) + if (FAILED(hr = init_font_collection(collection, factory, family_model))) { free(collection); return hr; @@ -5281,7 +5228,7 @@ HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, FALSE); + hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); if (FAILED(hr)) { free(collection);
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/dwrite_private.h | 2 +- dlls/dwrite/font.c | 34 +++++++++++++++++++++------------- dlls/dwrite/main.c | 8 ++++---- 3 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 688ac2d12f6..345c64277da 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -376,7 +376,7 @@ extern void factory_unlock(IDWriteFactory7 *factory); extern HRESULT create_inmemory_fileloader(IDWriteInMemoryFontFileLoader **loader); extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index, IDWriteFontResource **resource); -extern HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2 **ret); +extern HRESULT create_fontset_builder(IDWriteFactory7 *factory, BOOL is_system, IDWriteFontSetBuilder2 **ret); extern HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins); extern HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet *set, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 4eb9961d8df..c7fade678bf 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -485,6 +485,8 @@ struct dwrite_fontset
struct dwrite_fontset_entry **entries; unsigned int count; + + BOOL is_system; };
struct dwrite_fontset_builder @@ -496,6 +498,8 @@ struct dwrite_fontset_builder struct dwrite_fontset_entry **entries; size_t count; size_t capacity; + + BOOL is_system; };
static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, @@ -4898,6 +4902,9 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet } }
+ if (set->is_system) + fontcollection_add_replacements(collection); + hr = IDWriteFontCollection3_QueryInterface(&collection->IDWriteFontCollection3_iface, riid, ret); IDWriteFontCollection3_Release(&collection->IDWriteFontCollection3_iface);
@@ -7715,7 +7722,7 @@ static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontse }
static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory, - struct dwrite_fontset_entry **entries, unsigned int count); + struct dwrite_fontset_entry **entries, unsigned int count, BOOL is_system);
static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface) { @@ -7908,7 +7915,7 @@ static HRESULT WINAPI dwritefontset_GetMatchingFonts(IDWriteFontSet3 *iface, DWR entries = NULL; }
- init_fontset(object, set->factory, entries, matched_count); + init_fontset(object, set->factory, entries, matched_count, FALSE);
*filtered_set = (IDWriteFontSet *)&object->IDWriteFontSet3_iface;
@@ -8115,7 +8122,7 @@ static HRESULT fontset_create_entry(IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE }
static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory, - struct dwrite_fontset_entry **entries, unsigned int count) + struct dwrite_fontset_entry **entries, unsigned int count, BOOL is_system) { object->IDWriteFontSet3_iface.lpVtbl = &fontsetvtbl; object->refcount = 1; @@ -8123,6 +8130,7 @@ static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory IDWriteFactory7_AddRef(object->factory); object->entries = entries; object->count = count; + object->is_system = is_system; }
static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, @@ -8147,15 +8155,14 @@ static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dw fonts[i]->simulations, &entries[i]); } } - init_fontset(object, factory, entries, count); + init_fontset(object, factory, entries, count, FALSE);
*ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface;
return S_OK; }
-static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry **src_entries, - unsigned int count, IDWriteFontSet **ret) +static HRESULT fontset_builder_create_fontset(struct dwrite_fontset_builder *builder, IDWriteFontSet **ret) { struct dwrite_fontset_entry **entries = NULL; struct dwrite_fontset *object; @@ -8164,14 +8171,14 @@ static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct d if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (count) + if (builder->count) { - entries = calloc(count, sizeof(*entries)); + entries = calloc(builder->count, sizeof(*entries));
- for (i = 0; i < count; ++i) - entries[i] = addref_fontset_entry(src_entries[i]); + for (i = 0; i < builder->count; ++i) + entries[i] = addref_fontset_entry(builder->entries[i]); } - init_fontset(object, factory, entries, count); + init_fontset(object, builder->factory, entries, builder->count, builder->is_system);
*ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface;
@@ -8325,7 +8332,7 @@ static HRESULT WINAPI dwritefontsetbuilder_CreateFontSet(IDWriteFontSetBuilder2
TRACE("%p, %p.\n", iface, fontset);
- return fontset_builder_create_fontset(builder->factory, builder->entries, builder->count, fontset); + return fontset_builder_create_fontset(builder, fontset); }
static HRESULT WINAPI dwritefontsetbuilder1_AddFontFile(IDWriteFontSetBuilder2 *iface, IDWriteFontFile *file) @@ -8378,7 +8385,7 @@ static const IDWriteFontSetBuilder2Vtbl fontsetbuildervtbl = dwritefontsetbuilder2_AddFontFile, };
-HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2 **ret) +HRESULT create_fontset_builder(IDWriteFactory7 *factory, BOOL is_system, IDWriteFontSetBuilder2 **ret) { struct dwrite_fontset_builder *builder;
@@ -8389,6 +8396,7 @@ HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2
builder->IDWriteFontSetBuilder2_iface.lpVtbl = &fontsetbuildervtbl; builder->refcount = 1; + builder->is_system = is_system; builder->factory = factory; IDWriteFactory7_AddRef(builder->factory);
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index d4ae2bf4477..b25dd8b4053 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1632,7 +1632,7 @@ HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj)
*obj = NULL;
- if (FAILED(hr = create_fontset_builder(factory, &builder))) return hr; + if (FAILED(hr = create_fontset_builder(factory, TRUE, &builder))) return hr;
if (SUCCEEDED(hr = create_system_path_list(&paths, &count))) { @@ -1677,7 +1677,7 @@ static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory7 *iface { TRACE("%p, %p.\n", iface, builder);
- return create_fontset_builder(iface, (IDWriteFontSetBuilder2 **)builder); + return create_fontset_builder(iface, FALSE, (IDWriteFontSetBuilder2 **)builder); }
static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset, @@ -1796,7 +1796,7 @@ static HRESULT WINAPI dwritefactory5_CreateFontSetBuilder(IDWriteFactory7 *iface { TRACE("%p, %p.\n", iface, builder);
- return create_fontset_builder(iface, (IDWriteFontSetBuilder2 **)builder); + return create_fontset_builder(iface, FALSE, (IDWriteFontSetBuilder2 **)builder); }
static HRESULT WINAPI dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory7 *iface, @@ -1885,7 +1885,7 @@ static HRESULT WINAPI dwritefactory6_CreateFontSetBuilder(IDWriteFactory7 *iface { TRACE("%p, %p.\n", iface, builder);
- return create_fontset_builder(iface, builder); + return create_fontset_builder(iface, FALSE, builder); }
static HRESULT WINAPI dwritefactory6_CreateTextFormat(IDWriteFactory7 *iface, const WCHAR *family_name,
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/font.c | 191 +-------------------------------------------- 1 file changed, 3 insertions(+), 188 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c7fade678bf..8af7cf34296 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -4911,61 +4911,6 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet return hr; }
-struct system_fontfile_enumerator -{ - IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface; - LONG refcount; - - IDWriteFactory7 *factory; - HKEY hkey; - int index; - - WCHAR *filename; - DWORD filename_size; -}; - -static inline struct system_fontfile_enumerator *impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator* iface) -{ - return CONTAINING_RECORD(iface, struct system_fontfile_enumerator, IDWriteFontFileEnumerator_iface); -} - -static HRESULT WINAPI systemfontfileenumerator_QueryInterface(IDWriteFontFileEnumerator *iface, REFIID riid, void **obj) -{ - if (IsEqualIID(riid, &IID_IDWriteFontFileEnumerator) || IsEqualIID(riid, &IID_IUnknown)) { - IDWriteFontFileEnumerator_AddRef(iface); - *obj = iface; - return S_OK; - } - - WARN("%s not implemented.\n", debugstr_guid(riid)); - - *obj = NULL; - - return E_NOINTERFACE; -} - -static ULONG WINAPI systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator *iface) -{ - struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - return InterlockedIncrement(&enumerator->refcount); -} - -static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *iface) -{ - struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - ULONG refcount = InterlockedDecrement(&enumerator->refcount); - - if (!refcount) - { - IDWriteFactory7_Release(enumerator->factory); - RegCloseKey(enumerator->hkey); - free(enumerator->filename); - free(enumerator); - } - - return refcount; -} - static HRESULT create_local_file_reference(IDWriteFactory7 *factory, const WCHAR *filename, IDWriteFontFile **file) { HRESULT hr; @@ -4987,148 +4932,18 @@ static HRESULT create_local_file_reference(IDWriteFactory7 *factory, const WCHAR return hr; }
-static HRESULT WINAPI systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFileEnumerator *iface, IDWriteFontFile **file) -{ - struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - - *file = NULL; - - if (enumerator->index < 0 || !enumerator->filename || !*enumerator->filename) - return E_FAIL; - - return create_local_file_reference(enumerator->factory, enumerator->filename, file); -} - -static HRESULT WINAPI systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator *iface, BOOL *current) -{ - struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - WCHAR name_buf[256], *name = name_buf; - DWORD name_count, max_name_count = ARRAY_SIZE(name_buf), type, data_size; - HRESULT hr = S_OK; - LONG r; - - *current = FALSE; - enumerator->index++; - - /* iterate until we find next string value */ - for (;;) { - do { - name_count = max_name_count; - data_size = enumerator->filename_size - sizeof(*enumerator->filename); - - r = RegEnumValueW(enumerator->hkey, enumerator->index, name, &name_count, - NULL, &type, (BYTE *)enumerator->filename, &data_size); - if (r == ERROR_MORE_DATA) { - if (name_count >= max_name_count) { - if (name != name_buf) free(name); - max_name_count *= 2; - name = malloc(max_name_count * sizeof(*name)); - if (!name) return E_OUTOFMEMORY; - } - if (data_size > enumerator->filename_size - sizeof(*enumerator->filename)) - { - free(enumerator->filename); - enumerator->filename_size = max(data_size + sizeof(*enumerator->filename), enumerator->filename_size * 2); - if (!(enumerator->filename = malloc(enumerator->filename_size))) - { - hr = E_OUTOFMEMORY; - goto err; - } - } - } - } while (r == ERROR_MORE_DATA); - - if (r != ERROR_SUCCESS) { - enumerator->filename[0] = 0; - break; - } - enumerator->filename[data_size / sizeof(*enumerator->filename)] = 0; - if (type == REG_SZ && *name != '@') { - *current = TRUE; - break; - } - enumerator->index++; - } - TRACE("index = %d, current = %d\n", enumerator->index, *current); - -err: - if (name != name_buf) free(name); - return hr; -} - -static const IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl = -{ - systemfontfileenumerator_QueryInterface, - systemfontfileenumerator_AddRef, - systemfontfileenumerator_Release, - systemfontfileenumerator_MoveNext, - systemfontfileenumerator_GetCurrentFontFile -}; - -static HRESULT create_system_fontfile_enumerator(IDWriteFactory7 *factory, IDWriteFontFileEnumerator **ret) -{ - struct system_fontfile_enumerator *enumerator; - - *ret = NULL; - - if (!(enumerator = calloc(1, sizeof(*enumerator)))) - return E_OUTOFMEMORY; - - enumerator->IDWriteFontFileEnumerator_iface.lpVtbl = &systemfontfileenumeratorvtbl; - enumerator->refcount = 1; - enumerator->factory = factory; - enumerator->index = -1; - enumerator->filename_size = MAX_PATH * sizeof(*enumerator->filename); - enumerator->filename = malloc(enumerator->filename_size); - if (!enumerator->filename) - { - free(enumerator); - return E_OUTOFMEMORY; - } - - IDWriteFactory7_AddRef(factory); - - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Windows NT\CurrentVersion\Fonts", 0, - GENERIC_READ, &enumerator->hkey)) - { - ERR("failed to open fonts list key\n"); - IDWriteFactory7_Release(factory); - free(enumerator->filename); - free(enumerator); - return E_FAIL; - } - - *ret = &enumerator->IDWriteFontFileEnumerator_iface; - - return S_OK; -} - HRESULT get_system_fontcollection(IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection **collection) { - IDWriteFontFileEnumerator *enumerator; IDWriteFontSet *fontset; HRESULT hr;
*collection = NULL;
- if (family_model == DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC) + if (SUCCEEDED(hr = create_system_fontset(factory, &IID_IDWriteFontSet, (void **)&fontset))) { - 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); - } + hr = create_font_collection_from_set(factory, fontset, family_model, &IID_IDWriteFontCollection, (void **)collection); + IDWriteFontSet_Release(fontset); }
return hr;
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/dwrite_private.h | 4 +- dlls/dwrite/font.c | 131 ++++++----------------------------- dlls/dwrite/main.c | 2 +- 3 files changed, 24 insertions(+), 113 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 345c64277da..dc25ce351c6 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -338,8 +338,8 @@ extern void init_local_fontfile_loader(void); extern IDWriteFontFileLoader *get_local_fontfile_loader(void); extern HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace5 **fontface); -extern HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, - IDWriteFontCollection3 **collection); +extern HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, + IDWriteFontCollection3 **collection); extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**); extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*); extern HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**); diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 8af7cf34296..f89df74f054 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -4640,49 +4640,32 @@ static void fontcollection_add_replacements(struct dwrite_fontcollection *collec RegCloseKey(hkey); }
-HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system, - IDWriteFontCollection3 **ret) +HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, IDWriteFontCollection3 **ret) { struct fontfile_enum { struct list entry; IDWriteFontFile *file; }; struct fontfile_enum *fileenum, *fileenum2; - struct dwrite_fontcollection *collection; struct list scannedfiles; - BOOL current = FALSE; - HRESULT hr = S_OK; - size_t i; + IDWriteFontSetBuilder1 *builder; + IDWriteFontSet *fontset = NULL; + BOOL current; + HRESULT hr;
*ret = NULL;
- if (!(collection = calloc(1, sizeof(*collection)))) - return E_OUTOFMEMORY; - - hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); - if (FAILED(hr)) - { - free(collection); + if (FAILED(hr = create_fontset_builder(factory, FALSE, (IDWriteFontSetBuilder2 **)&builder))) return hr; - } - - *ret = &collection->IDWriteFontCollection3_iface;
TRACE("building font collection:\n");
list_init(&scannedfiles); - while (hr == S_OK) { - DWRITE_FONT_FACE_TYPE face_type; - DWRITE_FONT_FILE_TYPE file_type; - BOOL supported, same = FALSE; - IDWriteFontFileStream *stream; - IDWriteFontFile *file; - UINT32 face_count;
- current = FALSE; - hr = IDWriteFontFileEnumerator_MoveNext(enumerator, ¤t); - if (FAILED(hr) || !current) - break; + while (IDWriteFontFileEnumerator_MoveNext(enumerator, ¤t) == S_OK && current) + { + IDWriteFontFile *file; + BOOL same = FALSE;
hr = IDWriteFontFileEnumerator_GetCurrentFontFile(enumerator, &file); if (FAILED(hr)) @@ -4699,88 +4682,21 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat continue; }
- if (FAILED(get_filestream_from_file(file, &stream))) { - IDWriteFontFile_Release(file); - continue; - } - - /* Unsupported formats are skipped. */ - hr = opentype_analyze_font(stream, &supported, &file_type, &face_type, &face_count); - if (FAILED(hr) || !supported || face_count == 0) { - TRACE("Unsupported font (%p, 0x%08lx, %d, %u)\n", file, hr, supported, face_count); - IDWriteFontFileStream_Release(stream); - IDWriteFontFile_Release(file); - hr = S_OK; - continue; - } - /* add to scanned list */ fileenum = malloc(sizeof(*fileenum)); fileenum->file = file; list_add_tail(&scannedfiles, &fileenum->entry);
- for (i = 0; i < face_count; ++i) - { - struct dwrite_font_data *font_data; - struct fontface_desc desc; - WCHAR familyW[255]; - UINT32 index; - - desc.factory = factory; - desc.face_type = face_type; - desc.file = file; - desc.stream = stream; - desc.index = i; - desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; - desc.font_data = NULL; - - /* Allocate an initialize new font data structure. */ - hr = init_font_data(&desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data); - if (FAILED(hr)) - { - /* move to next one */ - hr = S_OK; - continue; - } - - fontstrings_get_en_string(font_data->family_names, familyW, ARRAY_SIZE(familyW)); - - /* ignore dot named faces */ - if (familyW[0] == '.') - { - WARN("Ignoring face %s\n", debugstr_w(familyW)); - release_font_data(font_data); - continue; - } - - index = collection_find_family(collection, familyW); - if (index != ~0u) - hr = fontfamily_add_font(collection->family_data[index], font_data); - else { - struct dwrite_fontfamily_data *family_data; - - /* create and init new family */ - hr = init_fontfamily_data(font_data->family_names, &family_data); - if (hr == S_OK) { - /* add font to family, family - to collection */ - hr = fontfamily_add_font(family_data, font_data); - if (hr == S_OK) - hr = fontcollection_add_family(collection, family_data); - - if (FAILED(hr)) - release_fontfamily_data(family_data); - } - } + if (FAILED(hr = IDWriteFontSetBuilder1_AddFontFile(builder, file))) + break; + }
- if (FAILED(hr)) - { - release_font_data(font_data); - break; - } - } + if (SUCCEEDED(hr)) + hr = IDWriteFontSetBuilder1_CreateFontSet(builder, &fontset);
- IDWriteFontFileStream_Release(stream); - } + if (SUCCEEDED(hr)) + hr = create_font_collection_from_set(factory, fontset, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection3, (void **)ret);
LIST_FOR_EACH_ENTRY_SAFE(fileenum, fileenum2, &scannedfiles, struct fontfile_enum, entry) { @@ -4789,14 +4705,9 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat free(fileenum); }
- for (i = 0; i < collection->count; ++i) - { - fontfamily_add_bold_simulated_face(collection->family_data[i]); - fontfamily_add_oblique_simulated_face(collection->family_data[i]); - } - - if (is_system) - fontcollection_add_replacements(collection); + if (fontset) + IDWriteFontSet_Release(fontset); + IDWriteFontSetBuilder1_Release(builder);
return hr; } diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index b25dd8b4053..9c6afa5de98 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -823,7 +823,7 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory7 * if (FAILED(hr)) return hr;
- hr = create_font_collection(iface, enumerator, FALSE, (IDWriteFontCollection3 **)collection); + hr = create_font_collection(iface, enumerator, (IDWriteFontCollection3 **)collection); IDWriteFontFileEnumerator_Release(enumerator); return hr; }
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/font.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index f89df74f054..4852fef59e2 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -3542,7 +3542,7 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio return S_OK; }
-static HRESULT init_font_collection(struct dwrite_fontcollection *collection, IDWriteFactory7 *factory, +static void init_font_collection(struct dwrite_fontcollection *collection, IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model) { collection->IDWriteFontCollection3_iface.lpVtbl = &fontcollectionvtbl; @@ -3550,8 +3550,6 @@ static HRESULT init_font_collection(struct dwrite_fontcollection *collection, ID collection->factory = factory; IDWriteFactory7_AddRef(collection->factory); collection->family_model = family_model; - - return S_OK; }
HRESULT get_filestream_from_file(IDWriteFontFile *file, IDWriteFontFileStream **stream) @@ -4772,11 +4770,7 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- if (FAILED(hr = init_font_collection(collection, factory, family_model))) - { - free(collection); - return hr; - } + init_font_collection(collection, factory, family_model);
for (i = 0; i < set->count; ++i) { @@ -4961,12 +4955,7 @@ HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); - if (FAILED(hr)) - { - free(collection); - return hr; - } + init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE);
*ret = &collection->IDWriteFontCollection3_iface;
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/font.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 4852fef59e2..8750511bbc3 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -473,7 +473,10 @@ struct dwrite_fontset_entry_desc struct dwrite_fontset_entry { LONG refcount; - struct dwrite_fontset_entry_desc desc; + IDWriteFontFile *file; + DWRITE_FONT_FACE_TYPE face_type; + unsigned int face_index; + unsigned int simulations; IDWriteLocalizedStrings *props[DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME + 1]; };
@@ -4778,18 +4781,18 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet IDWriteFontFileStream *stream; struct fontface_desc desc;
- if (FAILED(get_filestream_from_file(entry->desc.file, &stream))) + if (FAILED(get_filestream_from_file(entry->file, &stream))) { WARN("Failed to get file stream.\n"); continue; }
desc.factory = factory; - desc.face_type = entry->desc.face_type; - desc.file = entry->desc.file; + desc.face_type = entry->face_type; + desc.file = entry->file; desc.stream = stream; - desc.index = entry->desc.face_index; - desc.simulations = entry->desc.simulations; + desc.index = entry->face_index; + desc.simulations = entry->simulations; desc.font_data = NULL;
if (FAILED(hr = collection_add_font_entry(collection, &desc))) @@ -7373,7 +7376,7 @@ static void release_fontset_entry(struct dwrite_fontset_entry *entry)
if (InterlockedDecrement(&entry->refcount) > 0) return; - IDWriteFontFile_Release(entry->desc.file); + IDWriteFontFile_Release(entry->file); for (i = 0; i < ARRAY_SIZE(entry->props); ++i) { if (entry->props[i] && entry->props[i] != MISSING_SET_PROP) @@ -7405,9 +7408,9 @@ static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontse return value; }
- get_filestream_from_file(entry->desc.file, &stream_desc.stream); - stream_desc.face_type = entry->desc.face_type; - stream_desc.face_index = entry->desc.face_index; + get_filestream_from_file(entry->file, &stream_desc.stream); + stream_desc.face_type = entry->face_type; + stream_desc.face_index = entry->face_index;
if (property == DWRITE_FONT_PROPERTY_ID_FULL_NAME) opentype_get_font_info_strings(&stream_desc, DWRITE_INFORMATIONAL_STRING_FULL_NAME, &value); @@ -7480,8 +7483,8 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, if (index >= set->count) return E_INVALIDARG;
- return IDWriteFactory7_CreateFontFaceReference_(set->factory, set->entries[index]->desc.file, - set->entries[index]->desc.face_index, set->entries[index]->desc.simulations, reference); + return IDWriteFactory7_CreateFontFaceReference_(set->factory, set->entries[index]->file, + set->entries[index]->face_index, set->entries[index]->simulations, reference); }
static HRESULT WINAPI dwritefontset_FindFontFaceReference(IDWriteFontSet3 *iface, @@ -7728,8 +7731,8 @@ static HRESULT WINAPI dwritefontset1_CreateFontResource(IDWriteFontSet3 *iface, if (index >= set->count) return E_INVALIDARG;
- return IDWriteFactory7_CreateFontResource(set->factory, set->entries[index]->desc.file, - set->entries[index]->desc.face_index, resource); + return IDWriteFactory7_CreateFontResource(set->factory, set->entries[index]->file, + set->entries[index]->face_index, resource); }
static HRESULT WINAPI dwritefontset1_CreateFontFace(IDWriteFontSet3 *iface, UINT32 index, IDWriteFontFace5 **fontface) @@ -7825,11 +7828,11 @@ static HRESULT fontset_create_entry(IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE return E_OUTOFMEMORY;
entry->refcount = 1; - entry->desc.file = file; - IDWriteFontFile_AddRef(entry->desc.file); - entry->desc.face_type = face_type; - entry->desc.face_index = face_index; - entry->desc.simulations = simulations; + entry->file = file; + IDWriteFontFile_AddRef(entry->file); + entry->face_type = face_type; + entry->face_index = face_index; + entry->simulations = simulations;
*ret = entry;
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/dwrite_private.h | 7 +++ dlls/dwrite/font.c | 66 +++++++++++++++++++-------- dlls/dwrite/main.c | 88 +++++++++++++++++++++++++++++++----- 3 files changed, 130 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index dc25ce351c6..0ce0984b23b 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -383,6 +383,13 @@ extern HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWrite DWRITE_FONT_FAMILY_MODEL family_model, REFGUID riid, void **ret); extern HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj);
+struct dwrite_fontset_entry; +extern void release_fontset_entry(struct dwrite_fontset_entry *); +extern HRESULT fontset_builder_get_entries(IDWriteFontSetBuilder2 *iface, struct dwrite_fontset_entry ***ret, + unsigned int *count); +extern HRESULT fontset_create_from_set(IDWriteFactory7 *factory, struct dwrite_fontset_entry **src_entries, + unsigned int count, BOOL is_system, IDWriteFontSet **ret); + struct dwrite_fontface;
extern float fontface_get_scaled_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode, diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 8750511bbc3..63a5f4e8dc7 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7370,7 +7370,7 @@ static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface)
#define MISSING_SET_PROP ((void *)0x1)
-static void release_fontset_entry(struct dwrite_fontset_entry *entry) +void release_fontset_entry(struct dwrite_fontset_entry *entry) { unsigned int i;
@@ -7391,6 +7391,25 @@ static struct dwrite_fontset_entry * addref_fontset_entry(struct dwrite_fontset_ return entry; }
+HRESULT fontset_builder_get_entries(IDWriteFontSetBuilder2 *iface, struct dwrite_fontset_entry ***ret, + unsigned int *count) +{ + struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface); + struct dwrite_fontset_entry **entries; + unsigned int i; + + if (!(entries = calloc(builder->count, sizeof(*entries)))) + return E_OUTOFMEMORY; + + for (i = 0; i < builder->count; ++i) + entries[i] = addref_fontset_entry(builder->entries[i]); + + *ret = entries; + *count = builder->count; + + return S_OK; +} + static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontset_entry *entry, DWRITE_FONT_PROPERTY_ID property) { @@ -7851,36 +7870,38 @@ static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory object->is_system = is_system; }
-static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, - unsigned int count, IDWriteFontSet1 **ret) +HRESULT fontset_create_from_set(IDWriteFactory7 *factory, struct dwrite_fontset_entry **src_entries, + unsigned int count, BOOL is_system, IDWriteFontSet **ret) { struct dwrite_fontset_entry **entries = NULL; struct dwrite_fontset *object; unsigned int i;
+ *ret = NULL; + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
if (count) { - entries = calloc(count, sizeof(*entries)); - - /* FIXME: set available properties too */ - - for (i = 0; i < count; ++i) + if (!(entries = calloc(count, sizeof(*entries)))) { - fontset_create_entry(fonts[i]->file, fonts[i]->face_type, fonts[i]->face_index, - fonts[i]->simulations, &entries[i]); + free(object); + return E_OUTOFMEMORY; } + + for (i = 0; i < count; ++i) + entries[i] = addref_fontset_entry(src_entries[i]); } - init_fontset(object, factory, entries, count, FALSE); + init_fontset(object, factory, entries, count, is_system);
- *ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface; + *ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface;
return S_OK; }
-static HRESULT fontset_builder_create_fontset(struct dwrite_fontset_builder *builder, IDWriteFontSet **ret) +static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, + unsigned int count, IDWriteFontSet1 **ret) { struct dwrite_fontset_entry **entries = NULL; struct dwrite_fontset *object; @@ -7889,16 +7910,21 @@ static HRESULT fontset_builder_create_fontset(struct dwrite_fontset_builder *bui if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- if (builder->count) + if (count) { - entries = calloc(builder->count, sizeof(*entries)); + entries = calloc(count, sizeof(*entries));
- for (i = 0; i < builder->count; ++i) - entries[i] = addref_fontset_entry(builder->entries[i]); + /* FIXME: set available properties too */ + + for (i = 0; i < count; ++i) + { + fontset_create_entry(fonts[i]->file, fonts[i]->face_type, fonts[i]->face_index, + fonts[i]->simulations, &entries[i]); + } } - init_fontset(object, builder->factory, entries, builder->count, builder->is_system); + init_fontset(object, factory, entries, count, FALSE);
- *ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface; + *ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface;
return S_OK; } @@ -8050,7 +8076,7 @@ static HRESULT WINAPI dwritefontsetbuilder_CreateFontSet(IDWriteFontSetBuilder2
TRACE("%p, %p.\n", iface, fontset);
- return fontset_builder_create_fontset(builder, fontset); + return fontset_create_from_set(builder->factory, builder->entries, builder->count, builder->is_system, fontset); }
static HRESULT WINAPI dwritefontsetbuilder1_AddFontFile(IDWriteFontSetBuilder2 *iface, IDWriteFontFile *file) diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 9c6afa5de98..b343d65631c 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -603,6 +603,13 @@ struct dwritefactory IDWriteGdiInterop1 *gdiinterop; IDWriteFontFallback1 *fallback;
+ struct + { + FILETIME timestamp; + struct dwrite_fontset_entry **entries; + unsigned int count; + } system_set; + IDWriteFontFileLoader *localfontfileloader; struct list localfontfaces;
@@ -636,6 +643,15 @@ static void release_fileloader(struct fileloader *fileloader) free(fileloader); }
+static void factory_cleanup_fontset(struct dwritefactory *factory) +{ + unsigned int i; + + for (i = 0; i < factory->system_set.count; ++i) + release_fontset_entry(factory->system_set.entries[i]); + memset(&factory->system_set, 0, sizeof(factory->system_set)); +} + static void release_dwritefactory(struct dwritefactory *factory) { struct fileloader *fileloader, *fileloader2; @@ -660,6 +676,7 @@ static void release_dwritefactory(struct dwritefactory *factory) if (factory->system_collections[i]) IDWriteFontCollection_Release(factory->system_collections[i]); } + factory_cleanup_fontset(factory); if (factory->eudc_collection) IDWriteFontCollection1_Release(factory->eudc_collection); if (factory->fallback) @@ -1524,6 +1541,16 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *if return hr; }
+static HKEY open_fonts_key(void) +{ + HKEY hkey = NULL; + + RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\Microsoft\Windows NT\CurrentVersion\Fonts", + 0, GENERIC_READ | KEY_QUERY_VALUE, &hkey); + + return hkey; +} + static HRESULT create_system_path_list(WCHAR ***ret, unsigned int *ret_count) { unsigned int index = 0, value_size, max_name_count; @@ -1533,11 +1560,8 @@ static HRESULT create_system_path_list(WCHAR ***ret, unsigned int *ret_count) HKEY hkey; LONG r;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows NT\CurrentVersion\Fonts", - 0, GENERIC_READ, &hkey)) - { + if (!(hkey = open_fonts_key())) return E_UNEXPECTED; - }
value_size = MAX_PATH * sizeof(*value); value = malloc(value_size); @@ -1616,23 +1640,37 @@ static HRESULT create_system_path_list(WCHAR ***ret, unsigned int *ret_count) return S_OK; }
+static void get_system_fonts_mtime(FILETIME *mtime) +{ + HKEY hkey; + + memset(mtime, 0, sizeof(*mtime)); + + if ((hkey = open_fonts_key())) + { + RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, mtime); + RegCloseKey(hkey); + } +} + static int __cdecl create_system_fontset_compare(const void *left, const void *right) { const WCHAR *_l = *(WCHAR **)left, *_r = *(WCHAR **)right; return wcsicmp(_l, _r); };
-HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) +static HRESULT factory_create_system_fontset(struct dwritefactory *factory, const FILETIME *timestamp) { IDWriteFontSetBuilder2 *builder; - IDWriteFontSet *fontset; unsigned int i, j, count; WCHAR **paths; HRESULT hr;
- *obj = NULL; + factory_cleanup_fontset(factory); + factory->system_set.timestamp = *timestamp;
- if (FAILED(hr = create_fontset_builder(factory, TRUE, &builder))) return hr; + if (FAILED(hr = create_fontset_builder(&factory->IDWriteFactory7_iface, TRUE, &builder))) return hr;
if (SUCCEEDED(hr = create_system_path_list(&paths, &count))) { @@ -1655,14 +1693,42 @@ HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) free(paths); }
- if (SUCCEEDED(hr = IDWriteFontSetBuilder2_CreateFontSet(builder, &fontset))) + hr = fontset_builder_get_entries(builder, &factory->system_set.entries, &factory->system_set.count); + IDWriteFontSetBuilder2_Release(builder); + + return hr; +} + +HRESULT create_system_fontset(IDWriteFactory7 *factory_iface, REFIID riid, void **obj) +{ + struct dwritefactory *factory = impl_from_IDWriteFactory7(factory_iface); + IDWriteFontSet *fontset; + FILETIME timestamp; + HRESULT hr = S_OK; + + *obj = NULL; + + get_system_fonts_mtime(×tamp); + + EnterCriticalSection(&factory->cs); + + if (CompareFileTime(×tamp, &factory->system_set.timestamp) > 0) + hr = factory_create_system_fontset(factory, ×tamp); + + if (SUCCEEDED(hr)) + { + hr = fontset_create_from_set(factory_iface, factory->system_set.entries, + factory->system_set.count, TRUE, &fontset); + } + + LeaveCriticalSection(&factory->cs); + + if (SUCCEEDED(hr)) { hr = IDWriteFontSet_QueryInterface(fontset, riid, obj); IDWriteFontSet_Release(fontset); }
- IDWriteFontSetBuilder2_Release(builder); - return hr; }
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/tests/font.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 9d31407cf94..ba93e9b2064 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -5505,7 +5505,9 @@ static void test_GetGlyphRunOutline(void) static void test_GetEudcFontCollection(void) { IDWriteFontCollection *coll, *coll2; + IDWriteFontCollection1 *collection1; IDWriteFactory1 *factory; + IDWriteFontSet *fontset; HRESULT hr; ULONG ref;
@@ -5523,9 +5525,19 @@ static void test_GetEudcFontCollection(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(factory, 2); ok(coll == coll2, "got %p, %p\n", coll, coll2); - IDWriteFontCollection_Release(coll); IDWriteFontCollection_Release(coll2);
+ if (SUCCEEDED(IDWriteFontCollection_QueryInterface(coll, &IID_IDWriteFontCollection1, (void **)&collection1))) + { + hr = IDWriteFontCollection1_GetFontSet(collection1, &fontset); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDWriteFontSet_Release(fontset); + IDWriteFontCollection1_Release(collection1); + } + + IDWriteFontCollection_Release(coll); + ref = IDWriteFactory1_Release(factory); ok(ref == 0, "factory not released, %lu\n", ref); }
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/dwrite/font.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 63a5f4e8dc7..44a27c924fd 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -344,6 +344,12 @@ struct dwrite_fontcollection struct dwrite_fontfamily_data **family_data; size_t size; size_t count; + + struct + { + struct dwrite_fontset_entry **entries; + unsigned int count; + } set; };
struct dwrite_fontfamily @@ -508,6 +514,12 @@ struct dwrite_fontset_builder static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, unsigned int count, IDWriteFontSet1 **ret);
+static struct dwrite_fontset_entry * addref_fontset_entry(struct dwrite_fontset_entry *entry) +{ + InterlockedIncrement(&entry->refcount); + return entry; +} + static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context) { struct dwrite_fontface *fontface = context; @@ -3262,6 +3274,8 @@ static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection3 *iface) factory_detach_fontcollection(collection->factory, iface); for (i = 0; i < collection->count; ++i) release_fontfamily_data(collection->family_data[i]); + for (i = 0; i < collection->set.count; ++i) + release_fontset_entry(collection->set.entries[i]); free(collection->family_data); free(collection); } @@ -3396,6 +3410,12 @@ static HRESULT fontset_create_from_font_collection(struct dwrite_fontcollection
*fontset = NULL;
+ /* TODO: create a set for EUDC collection to have a single path for all collection types */ + + if (collection->set.count) + return fontset_create_from_set(collection->factory, collection->set.entries, + collection->set.count, FALSE, (IDWriteFontSet **)fontset); + for (i = 0; i < collection->count; ++i) count += collection->family_data[i]->count;
@@ -4773,14 +4793,23 @@ HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
+ if (!(collection->set.entries = calloc(set->count, sizeof(*collection->set.entries)))) + { + free(collection); + return E_OUTOFMEMORY; + } + init_font_collection(collection, factory, family_model);
+ collection->set.count = set->count; for (i = 0; i < set->count; ++i) { const struct dwrite_fontset_entry *entry = set->entries[i]; IDWriteFontFileStream *stream; struct fontface_desc desc;
+ collection->set.entries[i] = addref_fontset_entry(set->entries[i]); + if (FAILED(get_filestream_from_file(entry->file, &stream))) { WARN("Failed to get file stream.\n"); @@ -7385,12 +7414,6 @@ void release_fontset_entry(struct dwrite_fontset_entry *entry) free(entry); }
-static struct dwrite_fontset_entry * addref_fontset_entry(struct dwrite_fontset_entry *entry) -{ - InterlockedIncrement(&entry->refcount); - return entry; -} - HRESULT fontset_builder_get_entries(IDWriteFontSetBuilder2 *iface, struct dwrite_fontset_entry ***ret, unsigned int *count) {
This is looking good to me and fixes the original motivating issue with Ubisoft Connect, as described in !8906. Thanks, Nikolay!