Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 3da6b555c02..8e173263ad5 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -496,9 +496,10 @@ static const struct dwrite_fonttable *get_fontface_cpal(struct dwrite_fontface * return &fontface->cpal; }
-static void addref_font_data(struct dwrite_font_data *data) +static struct dwrite_font_data * addref_font_data(struct dwrite_font_data *data) { InterlockedIncrement(&data->ref); + return data; }
static void release_font_data(struct dwrite_font_data *data) @@ -2645,9 +2646,7 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily2 *ifac { if (!func || func(family->data->fonts[i])) { - fonts->fonts[fonts->font_count] = family->data->fonts[i]; - addref_font_data(family->data->fonts[i]); - fonts->font_count++; + fonts->fonts[fonts->font_count++] = addref_font_data(family->data->fonts[i]); } }
@@ -5006,8 +5005,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li */ if (desc->font_data) { - font_data = desc->font_data; - addref_font_data(font_data); + font_data = addref_font_data(desc->font_data); } else {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 11 +++++----- dlls/dwrite/font.c | 47 +++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 6b74a23540a..ecbe1a389fa 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -258,9 +258,10 @@ struct dwrite_fontfallback_builder size_t count; };
-struct dwrite_numbersubstitution { +struct dwrite_numbersubstitution +{ IDWriteNumberSubstitution IDWriteNumberSubstitution_iface; - LONG ref; + LONG refcount;
DWRITE_NUMBER_SUBSTITUTION_METHOD method; WCHAR *locale; @@ -1871,7 +1872,7 @@ static HRESULT WINAPI dwritenumbersubstitution_QueryInterface(IDWriteNumberSubst static ULONG WINAPI dwritenumbersubstitution_AddRef(IDWriteNumberSubstitution *iface) { struct dwrite_numbersubstitution *object = impl_from_IDWriteNumberSubstitution(iface); - ULONG refcount = InterlockedIncrement(&object->ref); + ULONG refcount = InterlockedIncrement(&object->refcount);
TRACE("%p, refcount %d.\n", iface, refcount);
@@ -1881,7 +1882,7 @@ static ULONG WINAPI dwritenumbersubstitution_AddRef(IDWriteNumberSubstitution *i static ULONG WINAPI dwritenumbersubstitution_Release(IDWriteNumberSubstitution *iface) { struct dwrite_numbersubstitution *object = impl_from_IDWriteNumberSubstitution(iface); - ULONG refcount = InterlockedDecrement(&object->ref); + ULONG refcount = InterlockedDecrement(&object->refcount);
TRACE("%p, refcount %d.\n", iface, refcount);
@@ -1926,7 +1927,7 @@ HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD method, cons return E_OUTOFMEMORY;
substitution->IDWriteNumberSubstitution_iface.lpVtbl = &numbersubstitutionvtbl; - substitution->ref = 1; + substitution->refcount = 1; substitution->ignore_user_override = ignore_user_override; substitution->method = method; substitution->locale = heap_strdupW(locale); diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 8e173263ad5..4252a3698ba 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -71,7 +71,7 @@ struct dwrite_font_propvec {
struct dwrite_font_data { - LONG ref; + LONG refcount;
DWRITE_FONT_STYLE style; DWRITE_FONT_STRETCH stretch; @@ -498,7 +498,7 @@ static const struct dwrite_fonttable *get_fontface_cpal(struct dwrite_fontface *
static struct dwrite_font_data * addref_font_data(struct dwrite_font_data *data) { - InterlockedIncrement(&data->ref); + InterlockedIncrement(&data->refcount); return data; }
@@ -506,7 +506,7 @@ static void release_font_data(struct dwrite_font_data *data) { int i;
- if (InterlockedDecrement(&data->ref) > 0) + if (InterlockedDecrement(&data->refcount) > 0) return;
for (i = 0; i < ARRAY_SIZE(data->info_strings); ++i) @@ -3963,7 +3963,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo if (!data) return E_OUTOFMEMORY;
- data->ref = 1; + data->refcount = 1; data->file = desc->file; data->face_index = desc->index; data->face_type = desc->face_type; @@ -4024,7 +4024,7 @@ static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRI return E_OUTOFMEMORY;
*data = *src; - data->ref = 1; + data->refcount = 1; data->simulations |= sim; if (sim == DWRITE_FONT_SIMULATIONS_BOLD) data->weight = DWRITE_FONT_WEIGHT_BOLD; @@ -4448,7 +4448,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat struct system_fontfile_enumerator { IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface; - LONG ref; + LONG refcount;
IDWriteFactory7 *factory; HKEY hkey; @@ -4481,15 +4481,15 @@ static HRESULT WINAPI systemfontfileenumerator_QueryInterface(IDWriteFontFileEnu static ULONG WINAPI systemfontfileenumerator_AddRef(IDWriteFontFileEnumerator *iface) { struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - return InterlockedIncrement(&enumerator->ref); + return InterlockedIncrement(&enumerator->refcount); }
static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *iface) { struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface); - ULONG ref = InterlockedDecrement(&enumerator->ref); + ULONG refcount = InterlockedDecrement(&enumerator->refcount);
- if (!ref) + if (!refcount) { IDWriteFactory7_Release(enumerator->factory); RegCloseKey(enumerator->hkey); @@ -4497,7 +4497,7 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator * heap_free(enumerator); }
- return ref; + return refcount; }
static HRESULT create_local_file_reference(IDWriteFactory7 *factory, const WCHAR *filename, IDWriteFontFile **file) @@ -4614,7 +4614,7 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory7 *factory, IDWri return E_OUTOFMEMORY;
enumerator->IDWriteFontFileEnumerator_iface.lpVtbl = &systemfontfileenumeratorvtbl; - enumerator->ref = 1; + enumerator->refcount = 1; enumerator->factory = factory; enumerator->index = -1; enumerator->filename_size = MAX_PATH * sizeof(*enumerator->filename); @@ -5085,7 +5085,7 @@ static struct dwrite_localfontfileloader local_fontfile_loader;
struct dwrite_inmemory_stream_data { - LONG ref; + LONG refcount; IUnknown *owner; void *data; UINT32 size; @@ -5094,7 +5094,7 @@ struct dwrite_inmemory_stream_data struct dwrite_inmemory_filestream { IDWriteFontFileStream IDWriteFontFileStream_iface; - LONG ref; + LONG refcount;
struct dwrite_inmemory_stream_data *data; }; @@ -5102,7 +5102,7 @@ struct dwrite_inmemory_filestream struct dwrite_inmemory_fileloader { IDWriteInMemoryFontFileLoader IDWriteInMemoryFontFileLoader_iface; - LONG ref; + LONG refcount;
struct dwrite_inmemory_stream_data **streams; size_t size; @@ -5131,7 +5131,8 @@ static inline struct dwrite_inmemory_filestream *inmemory_impl_from_IDWriteFontF
static void release_inmemory_stream(struct dwrite_inmemory_stream_data *stream) { - if (InterlockedDecrement(&stream->ref) == 0) { + if (InterlockedDecrement(&stream->refcount) == 0) + { if (stream->owner) IUnknown_Release(stream->owner); else @@ -6638,7 +6639,7 @@ static HRESULT WINAPI inmemoryfilestream_QueryInterface(IDWriteFontFileStream *i static ULONG WINAPI inmemoryfilestream_AddRef(IDWriteFontFileStream *iface) { struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface); - ULONG refcount = InterlockedIncrement(&stream->ref); + ULONG refcount = InterlockedIncrement(&stream->refcount);
TRACE_(dwrite_file)("%p, refcount %u.\n", iface, refcount);
@@ -6648,7 +6649,7 @@ static ULONG WINAPI inmemoryfilestream_AddRef(IDWriteFontFileStream *iface) static ULONG WINAPI inmemoryfilestream_Release(IDWriteFontFileStream *iface) { struct dwrite_inmemory_filestream *stream = inmemory_impl_from_IDWriteFontFileStream(iface); - ULONG refcount = InterlockedDecrement(&stream->ref); + ULONG refcount = InterlockedDecrement(&stream->refcount);
TRACE_(dwrite_file)("%p, refcount %u.\n", iface, refcount);
@@ -6739,7 +6740,7 @@ static HRESULT WINAPI inmemoryfontfileloader_QueryInterface(IDWriteInMemoryFontF static ULONG WINAPI inmemoryfontfileloader_AddRef(IDWriteInMemoryFontFileLoader *iface) { struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface); - ULONG refcount = InterlockedIncrement(&loader->ref); + ULONG refcount = InterlockedIncrement(&loader->refcount);
TRACE("%p, refcount %u.\n", iface, refcount);
@@ -6749,7 +6750,7 @@ static ULONG WINAPI inmemoryfontfileloader_AddRef(IDWriteInMemoryFontFileLoader static ULONG WINAPI inmemoryfontfileloader_Release(IDWriteInMemoryFontFileLoader *iface) { struct dwrite_inmemory_fileloader *loader = impl_from_IDWriteInMemoryFontFileLoader(iface); - ULONG refcount = InterlockedDecrement(&loader->ref); + ULONG refcount = InterlockedDecrement(&loader->refcount); size_t i;
TRACE("%p, refcount %u.\n", iface, refcount); @@ -6788,9 +6789,9 @@ static HRESULT WINAPI inmemoryfontfileloader_CreateStreamFromKey(IDWriteInMemory return E_OUTOFMEMORY;
stream->IDWriteFontFileStream_iface.lpVtbl = &inmemoryfilestreamvtbl; - stream->ref = 1; + stream->refcount = 1; stream->data = loader->streams[index]; - InterlockedIncrement(&stream->data->ref); + InterlockedIncrement(&stream->data->refcount);
*ret = &stream->IDWriteFontFileStream_iface;
@@ -6814,7 +6815,7 @@ static HRESULT WINAPI inmemoryfontfileloader_CreateInMemoryFontFileReference(IDW if (!(stream = heap_alloc(sizeof(*stream)))) return E_OUTOFMEMORY;
- stream->ref = 1; + stream->refcount = 1; stream->size = data_size; stream->owner = owner; if (stream->owner) { @@ -6866,7 +6867,7 @@ HRESULT create_inmemory_fileloader(IDWriteInMemoryFontFileLoader **ret) return E_OUTOFMEMORY;
loader->IDWriteInMemoryFontFileLoader_iface.lpVtbl = &inmemoryfontfileloadervtbl; - loader->ref = 1; + loader->refcount = 1;
*ret = &loader->IDWriteInMemoryFontFileLoader_iface;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 4252a3698ba..1a54d2300b1 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -3653,6 +3653,10 @@ static BOOL is_known_weight_value(DWRITE_FONT_WEIGHT weight, WCHAR *nameW) static const WCHAR extrablackW[] = {'E','x','t','r','a',' ','B','l','a','c','k',0}; static const WCHAR extraboldW[] = {'E','x','t','r','a',' ','B','o','l','d',0}; static const WCHAR demiboldW[] = {'D','e','m','i',' ','B','o','l','d',0}; + static const WCHAR thinW[] = {'T','h','i','n',0}; + static const WCHAR lightW[] = {'L','i','g','h','t',0}; + static const WCHAR mediumW[] = {'M','e','d','i','u','m',0}; + static const WCHAR blackW[] = {'B','l','a','c','k',0}; const struct knownweight_entry *ptr;
static const struct knownweight_entry knownweights[] = {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/main.c | 159 +++++++++++++++++++++++++++++++++++++-- dlls/dwrite/tests/font.c | 25 ++++++ 2 files changed, 178 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 51020d6f586..3326b1550ce 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1509,11 +1509,152 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *if return hr; }
+static HRESULT create_system_path_list(WCHAR ***ret, unsigned int *ret_count) +{ + unsigned int index = 0, value_size, name_count, max_name_count, type, data_size; + WCHAR **paths = NULL, *name, *value = NULL; + size_t capacity = 0, count = 0; + HKEY hkey; + LONG r; + + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows NT\CurrentVersion\Fonts", + 0, GENERIC_READ, &hkey)) + { + return E_UNEXPECTED; + } + + value_size = MAX_PATH * sizeof(*value); + value = heap_alloc(value_size); + + max_name_count = MAX_PATH; + name = heap_alloc(max_name_count * sizeof(*name)); + + for (;;) + { + if (!value) + { + value_size = MAX_PATH * sizeof(*value); + value = heap_alloc(value_size); + } + + do + { + name_count = max_name_count; + data_size = value_size - sizeof(*value); + + r = RegEnumValueW(hkey, index, name, &name_count, NULL, &type, (BYTE *)value, &data_size); + if (r == ERROR_MORE_DATA) + { + if (name_count >= max_name_count) + { + max_name_count *= 2; + heap_free(name); + name = heap_alloc(max_name_count * sizeof(*name)); + } + + if (data_size > value_size - sizeof(*value)) + { + heap_free(value); + value_size = max(data_size + sizeof(*value), value_size * 2); + value = heap_alloc(value_size); + } + } + } while (r == ERROR_MORE_DATA); + + if (r != ERROR_SUCCESS) + break; + + value[data_size / sizeof(*value)] = 0; + if (type == REG_SZ && *name != '@') + { + if (dwrite_array_reserve((void **)&paths, &capacity, count + 1, sizeof(*paths))) + { + if (!strchrW(value, '\')) + { + static const WCHAR fontsW[] = {'\','f','o','n','t','s','\',0}; + WCHAR *ptrW; + + ptrW = heap_alloc((MAX_PATH + lstrlenW(value)) * sizeof(WCHAR)); + GetWindowsDirectoryW(ptrW, MAX_PATH); + lstrcatW(ptrW, fontsW); + lstrcatW(ptrW, value); + + heap_free(value); + value = ptrW; + } + + paths[count++] = value; + value = NULL; + } + } + index++; + } + + heap_free(name); + + *ret = paths; + *ret_count = count; + + RegCloseKey(hkey); + + return S_OK; +} + +static int create_system_fontset_compare(const void *left, const void *right) +{ + const WCHAR *_l = *(WCHAR **)left, *_r = *(WCHAR **)right; + return lstrcmpiW(_l, _r); +}; + +static HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) +{ + IDWriteFontSetBuilder2 *builder; + IDWriteFontSet *fontset; + unsigned int i, j, count; + WCHAR **paths; + HRESULT hr; + + *obj = NULL; + + if (FAILED(hr = create_fontset_builder(factory, &builder))) return hr; + + if (SUCCEEDED(hr = create_system_path_list(&paths, &count))) + { + /* Sort, skip duplicates. */ + + qsort(paths, count, sizeof(*paths), create_system_fontset_compare); + + for (i = 0, j = 0; i < count; ++i) + { + if (i != j && !lstrcmpiW(paths[i], paths[j])) continue; + + if (FAILED(hr = IDWriteFontSetBuilder2_AddFontFile(builder, paths[i])) && hr != DWRITE_E_FILEFORMAT) + WARN("Failed to add font file, hr %#x, path %s.\n", hr, debugstr_w(paths[i])); + + j = i; + } + + for (i = 0; i < count; ++i) + heap_free(paths[i]); + heap_free(paths); + } + + if (SUCCEEDED(hr = IDWriteFontSetBuilder2_CreateFontSet(builder, &fontset))) + { + hr = IDWriteFontSet_QueryInterface(fontset, riid, obj); + IDWriteFontSet_Release(fontset); + } + + IDWriteFontSetBuilder2_Release(builder); + + return hr; +} + static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory7 *iface, IDWriteFontSet **fontset) { - FIXME("%p, %p: stub\n", iface, fontset); + TRACE("%p, %p.\n", iface, fontset);
- return E_NOTIMPL; + return create_system_fontset(iface, &IID_IDWriteFontSet, (void **)fontset); }
static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory7 *iface, IDWriteFontSetBuilder **builder) @@ -1691,9 +1832,12 @@ static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable, IDWriteFontSet1 **fontset) { - FIXME("%p, %d, %p.\n", iface, include_downloadable, fontset); + TRACE("%p, %d, %p.\n", iface, include_downloadable, fontset);
- return E_NOTIMPL; + if (include_downloadable) + FIXME("Downloadable fonts are not supported.\n"); + + return create_system_fontset(iface, &IID_IDWriteFontSet1, (void **)fontset); }
static HRESULT WINAPI dwritefactory6_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, @@ -1732,9 +1876,12 @@ static HRESULT WINAPI dwritefactory6_CreateTextFormat(IDWriteFactory7 *iface, co static HRESULT WINAPI dwritefactory7_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable, IDWriteFontSet2 **fontset) { - FIXME("%p, %d, %p.\n", iface, include_downloadable, fontset); + TRACE("%p, %d, %p.\n", iface, include_downloadable, fontset);
- return E_NOTIMPL; + if (include_downloadable) + FIXME("Downloadable fonts are not supported.\n"); + + return create_system_fontset(iface, &IID_IDWriteFontSet2, (void **)fontset); }
static HRESULT WINAPI dwritefactory7_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 4367f1d95c8..bded40a53c7 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -10009,6 +10009,30 @@ static void test_family_font_set(void) ok(!refcount, "Unexpected factory refcount %u.\n", refcount); }
+static void test_system_font_set(void) +{ + IDWriteFactory3 *factory; + IDWriteFontSet *fontset; + unsigned int count; + HRESULT hr; + + if (!(factory = create_factory_iid(&IID_IDWriteFactory3))) + { + win_skip("System font set is not supported.\n"); + return; + } + + hr = IDWriteFactory3_GetSystemFontSet(factory, &fontset); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + count = IDWriteFontSet_GetFontCount(fontset); + ok(!!count, "Unexpected font count %u.\n", count); + + IDWriteFontSet_Release(fontset); + + IDWriteFactory3_Release(factory); +} + START_TEST(font) { IDWriteFactory *factory; @@ -10081,6 +10105,7 @@ START_TEST(font) test_GetVerticalGlyphVariants(); test_expiration_event(); test_family_font_set(); + test_system_font_set();
IDWriteFactory_Release(factory); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/tests/font.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index bded40a53c7..d0940c3b145 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -10011,8 +10011,11 @@ static void test_family_font_set(void)
static void test_system_font_set(void) { + IDWriteFontSet *fontset, *filtered_set; + IDWriteFontFaceReference *ref; + IDWriteFontFace3 *fontface; IDWriteFactory3 *factory; - IDWriteFontSet *fontset; + DWRITE_FONT_PROPERTY p; unsigned int count; HRESULT hr;
@@ -10028,6 +10031,25 @@ static void test_system_font_set(void) count = IDWriteFontSet_GetFontCount(fontset); ok(!!count, "Unexpected font count %u.\n", count);
+ p.propertyId = DWRITE_FONT_PROPERTY_ID_FULL_NAME; + p.propertyValue = L"Tahoma"; + p.localeName = L""; + hr = IDWriteFontSet_GetMatchingFonts(fontset, &p, 1, &filtered_set); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + count = IDWriteFontSet_GetFontCount(filtered_set); + ok(!!count, "Unexpected font count %u.\n", count); + + hr = IDWriteFontSet_GetFontFaceReference(filtered_set, 0, &ref); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDWriteFontFaceReference_CreateFontFace(ref, &fontface); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IDWriteFontFace3_Release(fontface); + IDWriteFontFaceReference_Release(ref); + + IDWriteFontSet_Release(filtered_set); + IDWriteFontSet_Release(fontset);
IDWriteFactory3_Release(factory);