Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/main.c | 10 ++++--- dlls/dwrite/opentype.c | 51 ++++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index a91b8f99d70..7f7c933e7e2 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -298,6 +298,7 @@ extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const W extern HRESULT clone_localizedstrings(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN; extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; +extern unsigned int get_localizedstrings_count(IDWriteLocalizedStrings *strings) DECLSPEC_HIDDEN; extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN; extern HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN; extern IDWriteTextAnalyzer2 *get_text_analyzer(void) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index d66a27d7f68..4e308485a01 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -323,11 +323,9 @@ static ULONG WINAPI localizedstrings_Release(IDWriteLocalizedStrings *iface)
static UINT32 WINAPI localizedstrings_GetCount(IDWriteLocalizedStrings *iface) { - struct localizedstrings *strings = impl_from_IDWriteLocalizedStrings(iface); - TRACE("%p.\n", iface);
- return strings->count; + return get_localizedstrings_count(iface); }
static HRESULT WINAPI localizedstrings_FindLocaleName(IDWriteLocalizedStrings *iface, @@ -559,6 +557,12 @@ void sort_localizedstrings(IDWriteLocalizedStrings *iface) qsort(strings->data, strings->count, sizeof(*strings->data), localizedstrings_sorting_compare); }
+unsigned int get_localizedstrings_count(IDWriteLocalizedStrings *iface) +{ + struct localizedstrings *strings = impl_from_IDWriteLocalizedStrings(iface); + return strings->count; +} + struct collectionloader { struct list entry; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 717b1ea0351..a74c9712b6a 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -2288,9 +2288,21 @@ static void get_name_record_locale(enum OPENTYPE_PLATFORM_ID platform, USHORT la } }
+static BOOL opentype_is_english_namerecord(const struct dwrite_fonttable *table, unsigned int idx) +{ + const struct name_header *header = (const struct name_header *)table->data; + const struct name_record *record; + + record = &header->records[idx]; + + return GET_BE_WORD(record->platformID) == OPENTYPE_PLATFORM_MAC && + GET_BE_WORD(record->languageID) == TT_NAME_MAC_LANGID_ENGLISH; +} + static BOOL opentype_decode_namerecord(const struct dwrite_fonttable *table, unsigned int idx, IDWriteLocalizedStrings *strings) { + static const WCHAR enusW[] = {'e','n','-','U','S',0}; USHORT lang_id, length, offset, encoding, platform; const struct name_header *header = (const struct name_header *)table->data; const struct name_record *record; @@ -2338,7 +2350,8 @@ static BOOL opentype_decode_namerecord(const struct dwrite_fonttable *table, uns TRACE("string %s for locale %s found\n", debugstr_w(name_string), debugstr_w(locale)); add_localizedstring(strings, locale, name_string); heap_free(name_string); - ret = TRUE; + + ret = !lstrcmpW(locale, enusW); } else FIXME("handle NAME format 1\n"); @@ -2349,10 +2362,10 @@ static BOOL opentype_decode_namerecord(const struct dwrite_fonttable *table, uns static HRESULT opentype_get_font_strings_from_id(const struct dwrite_fonttable *table, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings) { - int i, count, candidate_mac, candidate_unicode; + int i, count, candidate_mac, candidate_mac_en, candidate_unicode; const struct name_record *records; + BOOL has_english; WORD format; - BOOL exists; HRESULT hr;
if (!table->data) @@ -2374,8 +2387,8 @@ static HRESULT opentype_get_font_strings_from_id(const struct dwrite_fonttable * count = 0; }
- exists = FALSE; - candidate_unicode = candidate_mac = -1; + has_english = FALSE; + candidate_unicode = candidate_mac = candidate_mac_en = -1;
for (i = 0; i < count; i++) { @@ -2398,10 +2411,11 @@ static HRESULT opentype_get_font_strings_from_id(const struct dwrite_fonttable * case OPENTYPE_PLATFORM_MAC: if (candidate_mac == -1) candidate_mac = i; + if (candidate_mac_en == -1 && opentype_is_english_namerecord(table, i)) + candidate_mac_en = i; break; case OPENTYPE_PLATFORM_WIN: - if (opentype_decode_namerecord(table, i, *strings)) - exists = TRUE; + has_english |= opentype_decode_namerecord(table, i, *strings); break; default: FIXME("platform %i not supported\n", platform); @@ -2409,24 +2423,23 @@ static HRESULT opentype_get_font_strings_from_id(const struct dwrite_fonttable * } }
- if (!exists) - { - if (candidate_mac != -1) - exists = opentype_decode_namerecord(table, candidate_mac, *strings); - if (!exists && candidate_unicode != -1) - exists = opentype_decode_namerecord(table, candidate_unicode, *strings); + if (!get_localizedstrings_count(*strings) && candidate_mac != -1) + has_english |= opentype_decode_namerecord(table, candidate_mac, *strings); + if (!get_localizedstrings_count(*strings) && candidate_unicode != -1) + has_english |= opentype_decode_namerecord(table, candidate_unicode, *strings); + if (!has_english && candidate_mac_en != -1) + opentype_decode_namerecord(table, candidate_mac_en, *strings);
- if (!exists) - { - IDWriteLocalizedStrings_Release(*strings); - *strings = NULL; - } + if (!get_localizedstrings_count(*strings)) + { + IDWriteLocalizedStrings_Release(*strings); + *strings = NULL; }
if (*strings) sort_localizedstrings(*strings);
- return exists ? S_OK : E_FAIL; + return *strings ? S_OK : E_FAIL; }
static WCHAR *meta_get_lng_name(WCHAR *str, WCHAR **ctx)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 4e308485a01..ea5a8e018cc 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -468,7 +468,7 @@ HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, if (*locale) { for (i = 0; i < count; i++) - if (!strcmpW(strings->data[i].locale, locale)) + if (!lstrcmpiW(strings->data[i].locale, locale)) return S_OK; }
@@ -483,6 +483,7 @@ HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, heap_free(strings->data[count].string); return E_OUTOFMEMORY; } + strlwrW(strings->data[count].locale);
strings->count++;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 105 +++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 41 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 1afc72e22c5..07d96dfe107 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -252,6 +252,7 @@ struct dwrite_fontresource
struct dwrite_fontset_entry { + LONG refcount; IDWriteFontFile *file; unsigned int face_index; unsigned int simulations; @@ -263,7 +264,7 @@ struct dwrite_fontset LONG refcount; IDWriteFactory7 *factory;
- struct dwrite_fontset_entry *entries; + struct dwrite_fontset_entry **entries; unsigned int count; };
@@ -273,7 +274,7 @@ struct dwrite_fontset_builder LONG refcount; IDWriteFactory7 *factory;
- struct dwrite_fontset_entry *entries; + struct dwrite_fontset_entry **entries; size_t count; size_t capacity; }; @@ -7103,25 +7104,27 @@ static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface) return refcount; }
-static void fontset_release_entries(struct dwrite_fontset_entry *entries, unsigned int count) +static void release_fontset_entry(struct dwrite_fontset_entry *entry) { - unsigned int i; - - for (i = 0; i < count; ++i) - IDWriteFontFile_Release(entries[i].file); + if (InterlockedDecrement(&entry->refcount) > 0) + return; + IDWriteFontFile_Release(entry->file); + heap_free(entry); }
static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface) { struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); ULONG refcount = InterlockedDecrement(&set->refcount); + unsigned int i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { IDWriteFactory7_Release(set->factory); - fontset_release_entries(set->entries, set->count); + for (i = 0; i < set->count; ++i) + release_fontset_entry(set->entries[i]); heap_free(set->entries); heap_free(set); } @@ -7142,7 +7145,6 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, IDWriteFontFaceReference **reference) { struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); - struct dwrite_fontset_entry *entry;
TRACE("%p, %u, %p.\n", iface, index, reference);
@@ -7151,9 +7153,8 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, if (index >= set->count) return E_INVALIDARG;
- entry = &set->entries[index]; - return IDWriteFactory7_CreateFontFaceReference_(set->factory, entry->file, entry->face_index, - entry->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, @@ -7386,65 +7387,85 @@ static const IDWriteFontSet3Vtbl fontsetvtbl = dwritefontset3_GetFontSourceName, };
-static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, - unsigned int count, IDWriteFontSet1 **ret) +static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_index, + unsigned int simulations, struct dwrite_fontset_entry **ret) { - struct dwrite_fontset *object; - unsigned int i; + struct dwrite_fontset_entry *entry;
- if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(entry = heap_alloc_zero(sizeof(*entry)))) return E_OUTOFMEMORY;
+ entry->refcount = 1; + entry->file = file; + IDWriteFontFile_AddRef(entry->file); + entry->face_index = face_index; + entry->simulations = simulations; + + *ret = entry; + + return S_OK; +} + +static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory, + struct dwrite_fontset_entry **entries, unsigned int count) +{ object->IDWriteFontSet3_iface.lpVtbl = &fontsetvtbl; object->refcount = 1; object->factory = factory; IDWriteFactory7_AddRef(object->factory); + object->entries = entries; + object->count = count; +} + +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; + unsigned int i; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY;
if (count) { - object->entries = heap_calloc(count, sizeof(*object->entries)); - object->count = count; + entries = heap_calloc(count, sizeof(*entries));
/* FIXME: set available properties too */ - for (i = 0; i < object->count; ++i) + + for (i = 0; i < count; ++i) { - object->entries[i].file = fonts[i]->file; - object->entries[i].face_index = fonts[i]->face_index; - object->entries[i].simulations = fonts[i]->simulations; - IDWriteFontFile_AddRef(object->entries[i].file); + fontset_create_entry(fonts[i]->file, fonts[i]->face_index, fonts[i]->simulations, &entries[i]); } } + init_fontset(object, factory, entries, count);
*ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface;
return S_OK; }
-static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry *entries, +static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry **src_entries, unsigned int count, IDWriteFontSet **ret) { + struct dwrite_fontset_entry **entries = NULL; struct dwrite_fontset *object; unsigned int i;
if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- object->IDWriteFontSet3_iface.lpVtbl = &fontsetvtbl; - object->refcount = 1; - object->factory = factory; - IDWriteFactory7_AddRef(object->factory); - if (count) { - object->entries = heap_calloc(count, sizeof(*object->entries)); - object->count = count; + entries = heap_calloc(count, sizeof(*entries));
- for (i = 0; i < object->count; ++i) + for (i = 0; i < count; ++i) { - object->entries[i] = entries[i]; - IDWriteFontFile_AddRef(object->entries[i].file); + entries[i] = src_entries[i]; + InterlockedIncrement(&entries[i]->refcount); } } + init_fontset(object, factory, entries, count);
*ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface;
@@ -7485,13 +7506,15 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface) { struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface); ULONG refcount = InterlockedDecrement(&builder->refcount); + unsigned int i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { IDWriteFactory7_Release(builder->factory); - fontset_release_entries(builder->entries, builder->count); + for (i = 0; i < builder->count; ++i) + release_fontset_entry(builder->entries[i]); heap_free(builder->entries); heap_free(builder); } @@ -7503,6 +7526,7 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, unsigned int face_index, unsigned int simulations) { struct dwrite_fontset_entry *entry; + HRESULT hr;
if (!dwrite_array_reserve((void **)&builder->entries, &builder->capacity, builder->count + 1, sizeof(*builder->entries))) @@ -7510,11 +7534,10 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, return E_OUTOFMEMORY; }
- entry = &builder->entries[builder->count++]; - entry->file = file; - IDWriteFontFile_AddRef(entry->file); - entry->face_index = face_index; - entry->simulations = simulations; + if (FAILED(hr = fontset_create_entry(file, face_index, simulations, &entry))) + return hr; + + builder->entries[builder->count++] = entry;
return S_OK; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 116 +++++++++++++++++++++++++++++++++------ dlls/dwrite/tests/font.c | 39 ++++++++++++- 2 files changed, 137 insertions(+), 18 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 07d96dfe107..c0642b5bbe4 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -254,8 +254,10 @@ struct dwrite_fontset_entry { LONG refcount; 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]; };
struct dwrite_fontset @@ -7104,14 +7106,74 @@ static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface) return refcount; }
+#define MISSING_SET_PROP ((void *)0x1) + static void release_fontset_entry(struct dwrite_fontset_entry *entry) { + unsigned int i; + if (InterlockedDecrement(&entry->refcount) > 0) return; IDWriteFontFile_Release(entry->file); + for (i = 0; i < ARRAY_SIZE(entry->props); ++i) + { + if (entry->props[i] && entry->props[i] != MISSING_SET_PROP) + IDWriteLocalizedStrings_Release(entry->props[i]); + } heap_free(entry); }
+static struct dwrite_fontset_entry * addref_fontset_entry(struct dwrite_fontset_entry *entry) +{ + InterlockedIncrement(&entry->refcount); + return entry; +} + +static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontset_entry *entry, + DWRITE_FONT_PROPERTY_ID property) +{ + struct file_stream_desc stream_desc = { 0 }; + IDWriteLocalizedStrings *value; + + assert(property > DWRITE_FONT_PROPERTY_ID_NONE && property <= DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME); + + if (entry->props[property] == MISSING_SET_PROP) + return NULL; + + if ((value = entry->props[property])) + { + IDWriteLocalizedStrings_AddRef(value); + return value; + } + + 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); + else if (property == DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME) + opentype_get_font_info_strings(&stream_desc, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &value); + else + WARN("Unsupported property %u.\n", property); + + if (stream_desc.stream) + IDWriteFontFileStream_Release(stream_desc.stream); + + if (value) + { + entry->props[property] = value; + IDWriteLocalizedStrings_AddRef(value); + } + else + entry->props[property] = MISSING_SET_PROP; + + return value; +} + +static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory, + struct dwrite_fontset_entry **entries, unsigned int count); + static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface) { struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); @@ -7192,12 +7254,22 @@ static HRESULT WINAPI dwritefontset_GetPropertyValues_(IDWriteFontSet3 *iface, D static HRESULT WINAPI dwritefontset_GetPropertyValues(IDWriteFontSet3 *iface, UINT32 index, DWRITE_FONT_PROPERTY_ID id, BOOL *exists, IDWriteLocalizedStrings **values) { - static int once; + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface);
- if (!once++) - FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values); + TRACE("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values);
- return E_NOTIMPL; + if (!(id > DWRITE_FONT_PROPERTY_ID_NONE && id <= DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME) || + index >= set->count) + { + *values = NULL; + *exists = FALSE; + return E_INVALIDARG; + } + + *values = fontset_entry_get_property(set->entries[index], id); + *exists = !!*values; + + return S_OK; }
static HRESULT WINAPI dwritefontset_GetPropertyOccurrenceCount(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *property, @@ -7387,8 +7459,8 @@ static const IDWriteFontSet3Vtbl fontsetvtbl = dwritefontset3_GetFontSourceName, };
-static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_index, - unsigned int simulations, struct dwrite_fontset_entry **ret) +static HRESULT fontset_create_entry(IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE face_type, + unsigned int face_index, unsigned int simulations, struct dwrite_fontset_entry **ret) { struct dwrite_fontset_entry *entry;
@@ -7398,6 +7470,7 @@ static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_ind entry->refcount = 1; entry->file = file; IDWriteFontFile_AddRef(entry->file); + entry->face_type = face_type; entry->face_index = face_index; entry->simulations = simulations;
@@ -7435,7 +7508,8 @@ static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dw
for (i = 0; i < count; ++i) { - fontset_create_entry(fonts[i]->file, fonts[i]->face_index, fonts[i]->simulations, &entries[i]); + fontset_create_entry(fonts[i]->file, fonts[i]->face_type, fonts[i]->face_index, + fonts[i]->simulations, &entries[i]); } } init_fontset(object, factory, entries, count); @@ -7460,10 +7534,7 @@ static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct d entries = heap_calloc(count, sizeof(*entries));
for (i = 0; i < count; ++i) - { - entries[i] = src_entries[i]; - InterlockedIncrement(&entries[i]->refcount); - } + entries[i] = addref_fontset_entry(src_entries[i]); } init_fontset(object, factory, entries, count);
@@ -7523,7 +7594,7 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface) }
static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, IDWriteFontFile *file, - unsigned int face_index, unsigned int simulations) + DWRITE_FONT_FACE_TYPE face_type, unsigned int face_index, unsigned int simulations) { struct dwrite_fontset_entry *entry; HRESULT hr; @@ -7534,7 +7605,7 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, return E_OUTOFMEMORY; }
- if (FAILED(hr = fontset_create_entry(file, face_index, simulations, &entry))) + if (FAILED(hr = fontset_create_entry(file, face_type, face_index, simulations, &entry))) return hr;
builder->entries[builder->count++] = entry; @@ -7558,7 +7629,7 @@ static HRESULT fontset_builder_add_file(struct dwrite_fontset_builder *builder,
for (i = 0; i < face_count; ++i) { - if (FAILED(hr = fontset_builder_add_entry(builder, file, i, DWRITE_FONT_SIMULATIONS_NONE))) + if (FAILED(hr = fontset_builder_add_entry(builder, file, facetype, i, DWRITE_FONT_SIMULATIONS_NONE))) break; }
@@ -7577,17 +7648,30 @@ static HRESULT WINAPI dwritefontsetbuilder_AddFontFaceReference(IDWriteFontSetBu IDWriteFontFaceReference *ref) { struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface); - unsigned int face_index, simulations; + unsigned int face_count, face_index, simulations; + DWRITE_FONT_FILE_TYPE file_type; + DWRITE_FONT_FACE_TYPE face_type; IDWriteFontFile *file; + BOOL supported; HRESULT hr;
TRACE("%p, %p.\n", iface, ref);
if (FAILED(hr = IDWriteFontFaceReference_GetFontFile(ref, &file))) return hr; + if (FAILED(hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count))) + goto done; + + if (!supported) + { + hr = DWRITE_E_FILEFORMAT; + goto done; + }
face_index = IDWriteFontFaceReference_GetFontFaceIndex(ref); simulations = IDWriteFontFaceReference_GetSimulations(ref); - hr = fontset_builder_add_entry(builder, file, face_index, simulations); + hr = fontset_builder_add_entry(builder, file, face_type, face_index, simulations); + +done: IDWriteFontFile_Release(file);
return hr; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 39a11b8be9a..4367f1d95c8 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -9505,7 +9505,6 @@ static void test_fontsetbuilder(void) BOOL exists = FALSE;
hr = IDWriteFontSet_GetPropertyValues(fontset, 0, id, &exists, &values); - todo_wine ok(hr == S_OK, "Failed to get property value, hr %#x.\n", hr);
if (!exists) @@ -9940,8 +9939,11 @@ static void test_family_font_set(void) IDWriteFontFamily2 *family2; IDWriteFontFamily *family; IDWriteFactory *factory; - unsigned int refcount; + unsigned int count, refcount; IDWriteFontSet1 *fontset, *fontset2; + IDWriteLocalizedStrings *values; + WCHAR buffW[64]; + BOOL exists; HRESULT hr;
factory = create_factory(); @@ -9959,6 +9961,39 @@ static void test_family_font_set(void) hr = IDWriteFontFamily2_GetFontSet(family2, &fontset2); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(fontset != fontset2, "Unexpected fontset instance.\n"); + + count = IDWriteFontSet1_GetFontCount(fontset); + + /* Invalid property id. */ + exists = TRUE; + values = (void *)0xdeadbeef; + hr = IDWriteFontSet1_GetPropertyValues(fontset, 0, 100, &exists, &values); + ok(FAILED(hr), "Unexpected hr %#x.\n", hr); + ok(!exists && !values, "Unexpected return value.\n"); + + /* Invalid index. */ + exists = TRUE; + values = (void *)0xdeadbeef; + hr = IDWriteFontSet1_GetPropertyValues(fontset, count, DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, &exists, &values); + ok(FAILED(hr), "Unexpected hr %#x.\n", hr); + ok(!exists && !values, "Unexpected return value.\n"); + + exists = TRUE; + values = (void *)0xdeadbeef; + hr = IDWriteFontSet1_GetPropertyValues(fontset, count, 100, &exists, &values); + ok(FAILED(hr), "Unexpected hr %#x.\n", hr); + ok(!exists && !values, "Unexpected return value.\n"); + + hr = IDWriteFontSet1_GetPropertyValues(fontset, 0, DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, &exists, &values); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(exists == !!values, "Unexpected return value.\n"); + if (values) + { + hr = IDWriteLocalizedStrings_GetString(values, 0, buffW, ARRAY_SIZE(buffW)); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IDWriteLocalizedStrings_Release(values); + } + IDWriteFontSet1_Release(fontset2); IDWriteFontSet1_Release(fontset);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 82 ++++++++++++++++++++++++++++++++++-- dlls/dwrite/main.c | 13 ++++++ 3 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 7f7c933e7e2..8c09a315f54 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -299,6 +299,7 @@ extern HRESULT clone_localizedstrings(IDWriteLocalizedStrings *iface, IDWriteLoc extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN; 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_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN; extern IDWriteTextAnalyzer2 *get_text_analyzer(void) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c0642b5bbe4..3da6b555c02 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7280,6 +7280,47 @@ static HRESULT WINAPI dwritefontset_GetPropertyOccurrenceCount(IDWriteFontSet3 * return E_NOTIMPL; }
+static BOOL fontset_entry_is_matching(struct dwrite_fontset_entry *entry, DWRITE_FONT_PROPERTY const *props, + unsigned int count) +{ + IDWriteLocalizedStrings *value; + unsigned int i; + BOOL ret; + + for (i = 0; i < count; ++i) + { + switch (props[i].propertyId) + { + case DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME: + case DWRITE_FONT_PROPERTY_ID_FULL_NAME: + if (!(value = fontset_entry_get_property(entry, props[i].propertyId))) + return FALSE; + + ret = localizedstrings_contains(value, props[i].propertyValue); + IDWriteLocalizedStrings_Release(value); + if (!ret) return FALSE; + break; + case DWRITE_FONT_PROPERTY_ID_WEIGHT_STRETCH_STYLE_FAMILY_NAME: + case DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FAMILY_NAME: + case DWRITE_FONT_PROPERTY_ID_WEIGHT_STRETCH_STYLE_FACE_NAME: + case DWRITE_FONT_PROPERTY_ID_WIN32_FAMILY_NAME: + case DWRITE_FONT_PROPERTY_ID_DESIGN_SCRIPT_LANGUAGE_TAG: + case DWRITE_FONT_PROPERTY_ID_SUPPORTED_SCRIPT_LANGUAGE_TAG: + case DWRITE_FONT_PROPERTY_ID_SEMANTIC_TAG: + case DWRITE_FONT_PROPERTY_ID_WEIGHT: + case DWRITE_FONT_PROPERTY_ID_STRETCH: + case DWRITE_FONT_PROPERTY_ID_STYLE: + case DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME: + FIXME("Unsupported property %d.\n", props[i].propertyId); + /* fallthrough */ + default: + return FALSE; + } + } + + return TRUE; +} + static HRESULT WINAPI dwritefontset_GetMatchingFonts_(IDWriteFontSet3 *iface, WCHAR const *family, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontSet **fontset) { @@ -7289,11 +7330,46 @@ static HRESULT WINAPI dwritefontset_GetMatchingFonts_(IDWriteFontSet3 *iface, WC }
static HRESULT WINAPI dwritefontset_GetMatchingFonts(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *props, UINT32 count, - IDWriteFontSet **fontset) + IDWriteFontSet **filtered_set) { - FIXME("%p, %p, %u, %p.\n", iface, props, count, fontset); + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); + struct dwrite_fontset_entry **entries; + unsigned int i, matched_count = 0; + struct dwrite_fontset *object;
- return E_NOTIMPL; + TRACE("%p, %p, %u, %p.\n", iface, props, count, filtered_set); + + if (!props && count) + return E_INVALIDARG; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + if (!(entries = heap_calloc(set->count, sizeof(*entries)))) + { + heap_free(object); + return E_OUTOFMEMORY; + } + + for (i = 0; i < set->count; ++i) + { + if (fontset_entry_is_matching(set->entries[i], props, count)) + { + entries[matched_count++] = addref_fontset_entry(set->entries[i]); + } + } + + if (!matched_count) + { + heap_free(entries); + entries = NULL; + } + + init_fontset(object, set->factory, entries, matched_count); + + *filtered_set = (IDWriteFontSet *)&object->IDWriteFontSet3_iface; + + return S_OK; }
static HRESULT WINAPI dwritefontset1_GetMatchingFonts(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *property, diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index ea5a8e018cc..51020d6f586 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -564,6 +564,19 @@ unsigned int get_localizedstrings_count(IDWriteLocalizedStrings *iface) return strings->count; }
+BOOL localizedstrings_contains(IDWriteLocalizedStrings *iface, const WCHAR *str) +{ + struct localizedstrings *strings = impl_from_IDWriteLocalizedStrings(iface); + unsigned int i; + + for (i = 0; i < strings->count; ++i) + { + if (!lstrcmpiW(strings->data[i].string, str)) return TRUE; + } + + return FALSE; +} + struct collectionloader { struct list entry;