Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 355 ++++++++++++++++++++++++++++++++++++++- dlls/dwrite/tests/font.c | 23 ++- 2 files changed, 361 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index bbd73f734de..ef61b173824 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -257,6 +257,16 @@ struct dwrite_fontset_entry unsigned int simulations; };
+struct dwrite_fontset +{ + IDWriteFontSet3 IDWriteFontSet3_iface; + LONG refcount; + IDWriteFactory7 *factory; + + struct dwrite_fontset_entry *entries; + unsigned int count; +}; + struct dwrite_fontset_builder { IDWriteFontSetBuilder2 IDWriteFontSetBuilder2_iface; @@ -396,6 +406,11 @@ static struct dwrite_fontset_builder *impl_from_IDWriteFontSetBuilder2(IDWriteFo return CONTAINING_RECORD(iface, struct dwrite_fontset_builder, IDWriteFontSetBuilder2_iface); }
+static struct dwrite_fontset *impl_from_IDWriteFontSet3(IDWriteFontSet3 *iface) +{ + return CONTAINING_RECORD(iface, struct dwrite_fontset, IDWriteFontSet3_iface); +} + static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) { static const DWRITE_GLYPH_METRICS nil; @@ -7080,6 +7095,336 @@ HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UI return S_OK; }
+static HRESULT WINAPI dwritefontset_QueryInterface(IDWriteFontSet3 *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IDWriteFontSet3) || + IsEqualIID(riid, &IID_IDWriteFontSet2) || + IsEqualIID(riid, &IID_IDWriteFontSet1) || + IsEqualIID(riid, &IID_IDWriteFontSet)) + { + *obj = iface; + IDWriteFontSet3_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface) +{ + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); + ULONG refcount = InterlockedIncrement(&set->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static void fontset_release_entries(struct dwrite_fontset_entry *entries, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; ++i) + IDWriteFontFile_Release(entries[i].file); +} + +static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface) +{ + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); + ULONG refcount = InterlockedDecrement(&set->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + IDWriteFactory7_Release(set->factory); + fontset_release_entries(set->entries, set->count); + heap_free(set->entries); + heap_free(set); + } + + return refcount; +} + +static UINT32 WINAPI dwritefontset_GetFontCount(IDWriteFontSet3 *iface) +{ + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); + + TRACE("%p.\n", iface); + + return set->count; +} + +static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, UINT32 index, + IDWriteFontFaceReference **reference) +{ + FIXME("%p, %u, %p.\n", iface, index, reference); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_FindFontFaceReference(IDWriteFontSet3 *iface, + IDWriteFontFaceReference *reference, UINT32 *index, BOOL *exists) +{ + FIXME("%p, %p, %p, %p.\n", iface, reference, index, exists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_FindFontFace(IDWriteFontSet3 *iface, IDWriteFontFace *fontface, + UINT32 *index, BOOL *exists) +{ + FIXME("%p, %p, %p, %p.\n", iface, fontface, index, exists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetPropertyValues__(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY_ID id, + IDWriteStringList **values) +{ + FIXME("%p, %d, %p.\n", iface, id, values); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetPropertyValues_(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY_ID id, + WCHAR const *preferred_locales, IDWriteStringList **values) +{ + FIXME("%p, %d, %s, %p.\n", iface, id, debugstr_w(preferred_locales), values); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetPropertyValues(IDWriteFontSet3 *iface, UINT32 index, DWRITE_FONT_PROPERTY_ID id, + BOOL *exists, IDWriteLocalizedStrings **values) +{ + FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetPropertyOccurrenceCount(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *property, + UINT32 *count) +{ + FIXME("%p, %p, %p.\n", iface, property, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetMatchingFonts_(IDWriteFontSet3 *iface, WCHAR const *family, DWRITE_FONT_WEIGHT weight, + DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontSet **fontset) +{ + FIXME("%p, %s, %d, %d, %d, %p.\n", iface, debugstr_w(family), weight, stretch, style, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset_GetMatchingFonts(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *props, UINT32 count, + IDWriteFontSet **fontset) +{ + FIXME("%p, %p, %u, %p.\n", iface, props, count, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetMatchingFonts(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *property, + DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values, IDWriteFontSet1 **fontset) +{ + FIXME("%p, %p, %p, %u, %p.\n", iface, property, axis_values, num_values, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFirstFontResources(IDWriteFontSet3 *iface, IDWriteFontSet1 **fontset) +{ + FIXME("%p, %p.\n", iface, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFilteredFonts__(IDWriteFontSet3 *iface, UINT32 const *indices, + UINT32 num_indices, IDWriteFontSet1 **fontset) +{ + FIXME("%p, %p, %u, %p.\n", iface, indices, num_indices, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFilteredFonts_(IDWriteFontSet3 *iface, DWRITE_FONT_AXIS_RANGE const *axis_ranges, + UINT32 num_ranges, BOOL select_any_range, IDWriteFontSet1 **fontset) +{ + FIXME("%p, %p, %u, %d, %p.\n", iface, axis_ranges, num_ranges, select_any_range, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFilteredFonts(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *props, + UINT32 num_properties, BOOL select_any_property, IDWriteFontSet1 **fontset) +{ + FIXME("%p, %p, %u, %d, %p.\n", iface, props, num_properties, select_any_property, fontset); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFilteredFontIndices_(IDWriteFontSet3 *iface, DWRITE_FONT_AXIS_RANGE const *ranges, + UINT32 num_ranges, BOOL select_any_range, UINT32 *indices, UINT32 num_indices, UINT32 *actual_num_indices) +{ + FIXME("%p, %p, %u, %d, %p, %u, %p.\n", iface, ranges, num_ranges, select_any_range, indices, num_indices, actual_num_indices); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFilteredFontIndices(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *props, + UINT32 num_properties, BOOL select_any_range, UINT32 *indices, UINT32 num_indices, UINT32 *actual_num_indices) +{ + FIXME("%p, %p, %u, %d, %p, %u, %p.\n", iface, props, num_properties, select_any_range, indices, + num_indices, actual_num_indices); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFontAxisRanges_(IDWriteFontSet3 *iface, UINT32 font_index, + DWRITE_FONT_AXIS_RANGE *axis_ranges, UINT32 num_ranges, UINT32 *actual_num_ranges) +{ + FIXME("%p, %u, %p, %u, %p.\n", iface, font_index, axis_ranges, num_ranges, actual_num_ranges); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFontAxisRanges(IDWriteFontSet3 *iface, DWRITE_FONT_AXIS_RANGE *axis_ranges, + UINT32 num_ranges, UINT32 *actual_num_ranges) +{ + FIXME("%p, %p, %u, %p.\n", iface, axis_ranges, num_ranges, actual_num_ranges); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_GetFontFaceReference(IDWriteFontSet3 *iface, UINT32 index, + IDWriteFontFaceReference1 **reference) +{ + FIXME("%p, %u, %p.\n", iface, index, reference); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_CreateFontResource(IDWriteFontSet3 *iface, UINT32 index, IDWriteFontResource **resource) +{ + FIXME("%p, %u, %p.\n", iface, index, resource); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontset1_CreateFontFace(IDWriteFontSet3 *iface, UINT32 index, IDWriteFontFace5 **fontface) +{ + FIXME("%p, %u, %p.\n", iface, index, fontface); + + return E_NOTIMPL; +} + +static DWRITE_LOCALITY WINAPI dwritefontset1_GetFontLocality(IDWriteFontSet3 *iface, UINT32 index) +{ + FIXME("%p, %u.\n", iface, index); + + return DWRITE_LOCALITY_LOCAL; +} + +static HANDLE WINAPI dwritefontset2_GetExpirationEvent(IDWriteFontSet3 *iface) +{ + FIXME("%p.\n", iface); + + return NULL; +} + +static DWRITE_FONT_SOURCE_TYPE WINAPI dwritefontset3_GetFontSourceType(IDWriteFontSet3 *iface, UINT32 index) +{ + FIXME("%p, %u.\n", iface, index); + + return DWRITE_FONT_SOURCE_TYPE_UNKNOWN; +} + +static UINT32 WINAPI dwritefontset3_GetFontSourceNameLength(IDWriteFontSet3 *iface, UINT32 index) +{ + FIXME("%p, %u.\n", iface, index); + + return 0; +} + +static HRESULT WINAPI dwritefontset3_GetFontSourceName(IDWriteFontSet3 *iface, UINT32 index, WCHAR *buffer, UINT32 buffer_size) +{ + FIXME("%p, %u, %p, %u.\n", iface, index, buffer, buffer_size); + + return E_NOTIMPL; +} + +static const IDWriteFontSet3Vtbl fontsetvtbl = +{ + dwritefontset_QueryInterface, + dwritefontset_AddRef, + dwritefontset_Release, + dwritefontset_GetFontCount, + dwritefontset_GetFontFaceReference, + dwritefontset_FindFontFaceReference, + dwritefontset_FindFontFace, + dwritefontset_GetPropertyValues__, + dwritefontset_GetPropertyValues_, + dwritefontset_GetPropertyValues, + dwritefontset_GetPropertyOccurrenceCount, + dwritefontset_GetMatchingFonts_, + dwritefontset_GetMatchingFonts, + dwritefontset1_GetMatchingFonts, + dwritefontset1_GetFirstFontResources, + dwritefontset1_GetFilteredFonts__, + dwritefontset1_GetFilteredFonts_, + dwritefontset1_GetFilteredFonts, + dwritefontset1_GetFilteredFontIndices_, + dwritefontset1_GetFilteredFontIndices, + dwritefontset1_GetFontAxisRanges_, + dwritefontset1_GetFontAxisRanges, + dwritefontset1_GetFontFaceReference, + dwritefontset1_CreateFontResource, + dwritefontset1_CreateFontFace, + dwritefontset1_GetFontLocality, + dwritefontset2_GetExpirationEvent, + dwritefontset3_GetFontSourceType, + dwritefontset3_GetFontSourceNameLength, + dwritefontset3_GetFontSourceName, +}; + +static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry *entries, + unsigned int count, IDWriteFontSet **ret) +{ + 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; + + for (i = 0; i < object->count; ++i) + { + object->entries[i] = entries[i]; + IDWriteFontFile_AddRef(object->entries[i].file); + } + } + + *ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface; + + return S_OK; +} + static HRESULT WINAPI dwritefontsetbuilder_QueryInterface(IDWriteFontSetBuilder2 *iface, REFIID riid, void **obj) { @@ -7114,15 +7459,13 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface) { struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface); ULONG refcount = InterlockedDecrement(&builder->refcount); - size_t i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { IDWriteFactory7_Release(builder->factory); - for (i = 0; i < builder->count; ++i) - IDWriteFontFile_Release(builder->entries[i].file); + fontset_release_entries(builder->entries, builder->count); heap_free(builder->entries); heap_free(builder); } @@ -7210,9 +7553,11 @@ static HRESULT WINAPI dwritefontsetbuilder_AddFontSet(IDWriteFontSetBuilder2 *if
static HRESULT WINAPI dwritefontsetbuilder_CreateFontSet(IDWriteFontSetBuilder2 *iface, IDWriteFontSet **fontset) { - FIXME("%p, %p.\n", iface, fontset); + struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, fontset); + + return fontset_builder_create_fontset(builder->factory, builder->entries, builder->count, fontset); }
static HRESULT WINAPI dwritefontsetbuilder1_AddFontFile(IDWriteFontSetBuilder2 *iface, IDWriteFontFile *file) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index c377f20556b..97caa7b31a2 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -9400,17 +9400,13 @@ static void test_fontsetbuilder(void) ok(hr == S_OK, "Unexpected hr %#x.\n",hr);
hr = IDWriteFontSetBuilder1_CreateFontSet(builder1, &fontset); - todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n",hr);
- if (SUCCEEDED(hr)) - { /* No attempt to eliminate duplicates. */ count = IDWriteFontSet_GetFontCount(fontset); ok(count == 2, "Unexpected font count %u.\n", count);
IDWriteFontSet_Release(fontset); - }
IDWriteFontFile_Release(file); IDWriteFontSetBuilder1_Release(builder1); @@ -9453,33 +9449,37 @@ static void test_fontsetbuilder(void) EXPECT_REF(ref, 1);
hr = IDWriteFontSetBuilder_CreateFontSet(builder, &fontset); - todo_wine ok(hr == S_OK, "Failed to create a font set, hr %#x.\n", hr);
- if (SUCCEEDED(hr)) - { setcount = IDWriteFontSet_GetFontCount(fontset); ok(setcount == 1, "Unexpected font count %u.\n", setcount);
+ ref2 = NULL; hr = IDWriteFontSet_GetFontFaceReference(fontset, 0, &ref2); + todo_wine ok(hr == S_OK, "Failed to get font face reference, hr %#x.\n", hr); ok(ref2 != ref, "Unexpected reference.\n");
+ ref3 = NULL; hr = IDWriteFontSet_GetFontFaceReference(fontset, 0, &ref3); + todo_wine { ok(hr == S_OK, "Failed to get font face reference, hr %#x.\n", hr); ok(ref2 != ref3, "Unexpected reference.\n"); - - IDWriteFontFaceReference_Release(ref3); - IDWriteFontFaceReference_Release(ref2); + } + if (ref3) + IDWriteFontFaceReference_Release(ref3); + if (ref2) + IDWriteFontFaceReference_Release(ref2);
for (id = DWRITE_FONT_PROPERTY_ID_FAMILY_NAME; id < DWRITE_FONT_PROPERTY_ID_TOTAL; ++id) { IDWriteLocalizedStrings *values; WCHAR buffW[255], buff2W[255]; UINT32 c, ivalue = 0; - BOOL exists; + 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) @@ -9529,7 +9529,6 @@ static void test_fontsetbuilder(void) }
IDWriteFontSet_Release(fontset); - } IDWriteFontFaceReference_Release(ref); IDWriteFontSetBuilder_Release(builder);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 14 ++++++++++++-- dlls/dwrite/tests/font.c | 15 ++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index ef61b173824..98c194b8c30 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7162,9 +7162,19 @@ static UINT32 WINAPI dwritefontset_GetFontCount(IDWriteFontSet3 *iface) static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, UINT32 index, IDWriteFontFaceReference **reference) { - FIXME("%p, %u, %p.\n", iface, index, reference); + struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface); + struct dwrite_fontset_entry *entry;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, index, reference); + + *reference = NULL; + + if (index >= set->count) + return E_INVALIDARG; + + entry = &set->entries[index]; + return IDWriteFactory7_CreateFontFaceReference_(set->factory, entry->file, entry->face_index, + entry->simulations, reference); }
static HRESULT WINAPI dwritefontset_FindFontFaceReference(IDWriteFontSet3 *iface, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 97caa7b31a2..4dcbbc4d077 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -9454,22 +9454,23 @@ static void test_fontsetbuilder(void) setcount = IDWriteFontSet_GetFontCount(fontset); ok(setcount == 1, "Unexpected font count %u.\n", setcount);
+ ref2 = (void *)0xdeadbeef; + hr = IDWriteFontSet_GetFontFaceReference(fontset, setcount, &ref2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + ok(!ref2, "Unexpected pointer.\n"); + ref2 = NULL; hr = IDWriteFontSet_GetFontFaceReference(fontset, 0, &ref2); - todo_wine ok(hr == S_OK, "Failed to get font face reference, hr %#x.\n", hr); ok(ref2 != ref, "Unexpected reference.\n");
ref3 = NULL; hr = IDWriteFontSet_GetFontFaceReference(fontset, 0, &ref3); - todo_wine { ok(hr == S_OK, "Failed to get font face reference, hr %#x.\n", hr); ok(ref2 != ref3, "Unexpected reference.\n"); - } - if (ref3) - IDWriteFontFaceReference_Release(ref3); - if (ref2) - IDWriteFontFaceReference_Release(ref2); + + IDWriteFontFaceReference_Release(ref3); + IDWriteFontFaceReference_Release(ref2);
for (id = DWRITE_FONT_PROPERTY_ID_FAMILY_NAME; id < DWRITE_FONT_PROPERTY_ID_TOTAL; ++id) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 98c194b8c30..b0b8e3c34f4 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7212,7 +7212,13 @@ 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) { - FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values); + static int once; + + if (!once++) + FIXME("%p: stub\n", iface); + + if (!once++) + FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values);
return E_NOTIMPL; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 44 ++++++++++++++++++++++++++++++++++++++-- dlls/dwrite/tests/font.c | 29 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index b0b8e3c34f4..b64ea53692f 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -278,6 +278,9 @@ struct dwrite_fontset_builder size_t capacity; };
+static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts, + unsigned int count, IDWriteFontSet1 **ret); + static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context) { struct dwrite_fontface *fontface = context; @@ -2385,9 +2388,12 @@ static HRESULT WINAPI dwritefontlist1_GetFontFaceReference(IDWriteFontList2 *ifa
static HRESULT WINAPI dwritefontlist2_GetFontSet(IDWriteFontList2 *iface, IDWriteFontSet1 **fontset) { - FIXME("%p, %p.\n", iface, fontset); + struct dwrite_fontlist *fontlist = impl_from_IDWriteFontList2(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, fontset); + + return fontset_create_from_font_data(fontlist->family->collection->factory, fontlist->fonts, + fontlist->font_count, fontset); }
static const IDWriteFontList2Vtbl dwritefontlistvtbl = @@ -7410,6 +7416,40 @@ 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) +{ + 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; + + /* FIXME: set available properties too */ + for (i = 0; i < object->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); + } + } + + *ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface; + + return S_OK; +} + static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry *entries, unsigned int count, IDWriteFontSet **ret) { diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 4dcbbc4d077..12ea78b634b 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -1626,7 +1626,24 @@ if (0) /* crashes on native */
if (SUCCEEDED(IDWriteFontFamily1_QueryInterface(family1, &IID_IDWriteFontList2, (void **)&fontlist2))) { + IDWriteFontSet1 *fontset = NULL, *fontset2 = NULL; + ok(fontlist == (IDWriteFontList *)fontlist2, "Unexpected interface pointer.\n"); + + hr = IDWriteFontList2_GetFontSet(fontlist2, &fontset); + todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDWriteFontList2_GetFontSet(fontlist2, &fontset2); + todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(fontset != fontset2, "Unexpected instance.\n"); + } + if (fontset2) + IDWriteFontSet1_Release(fontset2); + if (fontset) + IDWriteFontSet1_Release(fontset); + IDWriteFontList2_Release(fontlist2); } else @@ -4067,6 +4084,18 @@ static void test_GetMatchingFonts(void)
if (SUCCEEDED(IDWriteFontList_QueryInterface(fontlist, &IID_IDWriteFontList2, (void **)&fontlist3))) { + IDWriteFontSet1 *fontset, *fontset2; + + hr = IDWriteFontList2_GetFontSet(fontlist3, &fontset); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IDWriteFontList2_GetFontSet(fontlist3, &fontset2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(fontset != fontset2, "Unexpected instance.\n"); + + IDWriteFontSet1_Release(fontset2); + IDWriteFontSet1_Release(fontset); + IDWriteFontList2_Release(fontlist3); } else
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 14 ++++++++++---- dlls/dwrite/tests/font.c | 16 ++++------------ 2 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index b64ea53692f..9232f29317f 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -2725,9 +2725,12 @@ static HRESULT WINAPI dwritefontfamily2_GetMatchingFonts(IDWriteFontFamily2 *ifa
static HRESULT WINAPI dwritefontfamily2_GetFontSet(IDWriteFontFamily2 *iface, IDWriteFontSet1 **fontset) { - FIXME("%p, %p.\n", iface, fontset); + struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily2(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, fontset); + + return fontset_create_from_font_data(family->collection->factory, family->data->fonts, + family->data->count, fontset); }
static const IDWriteFontFamily2Vtbl fontfamilyvtbl = @@ -2806,9 +2809,12 @@ static HRESULT WINAPI dwritefontfamilylist1_GetFontFaceReference(IDWriteFontList
static HRESULT WINAPI dwritefontfamilylist2_GetFontSet(IDWriteFontList2 *iface, IDWriteFontSet1 **fontset) { - FIXME("%p, %p.\n", iface, fontset); + struct dwrite_fontfamily *family = impl_family_from_IDWriteFontList2(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, fontset); + + return fontset_create_from_font_data(family->collection->factory, family->data->fonts, + family->data->count, fontset); }
static const IDWriteFontList2Vtbl fontfamilylistvtbl = diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 12ea78b634b..8fe59ca5a1e 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -1631,18 +1631,14 @@ if (0) /* crashes on native */ ok(fontlist == (IDWriteFontList *)fontlist2, "Unexpected interface pointer.\n");
hr = IDWriteFontList2_GetFontSet(fontlist2, &fontset); - todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IDWriteFontList2_GetFontSet(fontlist2, &fontset2); - todo_wine { ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(fontset != fontset2, "Unexpected instance.\n"); - } - if (fontset2) - IDWriteFontSet1_Release(fontset2); - if (fontset) - IDWriteFontSet1_Release(fontset); + + IDWriteFontSet1_Release(fontset2); + IDWriteFontSet1_Release(fontset);
IDWriteFontList2_Release(fontlist2); } @@ -9959,17 +9955,13 @@ static void test_family_font_set(void) if (SUCCEEDED(IDWriteFontFamily_QueryInterface(family, &IID_IDWriteFontFamily2, (void **)&family2))) { hr = IDWriteFontFamily2_GetFontSet(family2, &fontset); - todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); hr = IDWriteFontFamily2_GetFontSet(family2, &fontset2); - todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - if (SUCCEEDED(hr)) - { ok(fontset != fontset2, "Unexpected fontset instance.\n"); IDWriteFontSet1_Release(fontset2); IDWriteFontSet1_Release(fontset); - } + IDWriteFontFamily2_Release(family2); } else