Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 507099b24e..a3d36a5206 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -2429,21 +2429,19 @@ static HRESULT WINAPI dwritefontfamily1_GetFont(IDWriteFontFamily2 *iface, UINT3 static HRESULT WINAPI dwritefontfamily1_GetFontFaceReference(IDWriteFontFamily2 *iface, UINT32 index, IDWriteFontFaceReference **reference) { - IDWriteFont3 *font; - HRESULT hr; + struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily2(iface); + const struct dwrite_font_data *font;
TRACE("%p, %u, %p.\n", iface, index, reference);
*reference = NULL;
- hr = IDWriteFontFamily2_GetFont(iface, index, &font); - if (FAILED(hr)) - return hr; - - hr = IDWriteFont3_GetFontFaceReference(font, reference); - IDWriteFont3_Release(font); + if (index >= family->data->count) + return E_FAIL;
- return hr; + font = family->data->fonts[index]; + return IDWriteFactory5_CreateFontFaceReference_((IDWriteFactory5 *)family->collection->factory, + font->file, font->face_index, font->simulations, reference); }
static HRESULT WINAPI dwritefontfamily2_GetMatchingFonts(IDWriteFontFamily2 *iface,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 203 ++++++++++++++++++++++++++++++++++- dlls/dwrite/tests/font.c | 28 ++--- 3 files changed, 211 insertions(+), 21 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 200a9d39ba..5755696875 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -195,6 +195,7 @@ enum font_flags struct dwrite_fontface { IDWriteFontFace5 IDWriteFontFace5_iface; + IDWriteFontFaceReference IDWriteFontFaceReference_iface; LONG refcount;
IDWriteFontFileStream *stream; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index a3d36a5206..fc0af3c79e 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -290,6 +290,11 @@ static inline struct dwrite_fontface *impl_from_IDWriteFontFace5(IDWriteFontFace return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace5_iface); }
+static struct dwrite_fontface *impl_from_IDWriteFontFaceReference(IDWriteFontFaceReference *iface) +{ + return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFaceReference_iface); +} + static inline struct dwrite_font *impl_from_IDWriteFont3(IDWriteFont3 *iface) { return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont3_iface); @@ -507,6 +512,14 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace5 *iface, REF IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; + } + else if (IsEqualIID(riid, &IID_IDWriteFontFaceReference)) + *obj = &fontface->IDWriteFontFaceReference_iface; + else + *obj = NULL; + + if (*obj) + { if (InterlockedIncrement(&fontface->refcount) == 1) { InterlockedDecrement(&fontface->refcount); @@ -518,7 +531,6 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace5 *iface, REF
WARN("%s not implemented.\n", debugstr_guid(riid));
- *obj = NULL; return E_NOINTERFACE; }
@@ -1249,11 +1261,17 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac return S_OK; }
-static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace5 *iface, IDWriteFontFaceReference **ref) +static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace5 *iface, + IDWriteFontFaceReference **reference) { - FIXME("%p, %p: stub\n", iface, ref); + struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, reference); + + *reference = &fontface->IDWriteFontFaceReference_iface; + IDWriteFontFaceReference_AddRef(*reference); + + return S_OK; }
static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace5 *iface, DWRITE_PANOSE *panose) @@ -1587,6 +1605,182 @@ static const IDWriteFontFace5Vtbl dwritefontfacevtbl = dwritefontface5_GetFontResource, };
+static HRESULT WINAPI dwritefontface_reference_QueryInterface(IDWriteFontFaceReference *iface, REFIID riid, void **obj) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + return IDWriteFontFace5_QueryInterface(&fontface->IDWriteFontFace5_iface, riid, obj); +} + +static ULONG WINAPI dwritefontface_reference_AddRef(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + return IDWriteFontFace5_AddRef(&fontface->IDWriteFontFace5_iface); +} + +static ULONG WINAPI dwritefontface_reference_Release(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + return IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface); +} + +static HRESULT WINAPI dwritefontface_reference_CreateFontFace(IDWriteFontFaceReference *iface, + IDWriteFontFace3 **ret) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + + TRACE("%p, %p.\n", iface, ret); + + *ret = (IDWriteFontFace3 *)&fontface->IDWriteFontFace5_iface; + IDWriteFontFace3_AddRef(*ret); + + return S_OK; +} + +static HRESULT WINAPI dwritefontface_reference_CreateFontFaceWithSimulations(IDWriteFontFaceReference *iface, + DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace3 **ret) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + DWRITE_FONT_FILE_TYPE file_type; + DWRITE_FONT_FACE_TYPE face_type; + IDWriteFontFace *face; + BOOL is_supported; + UINT32 face_num; + HRESULT hr; + + TRACE("%p, %#x, %p.\n", iface, simulations, ret); + + hr = IDWriteFontFile_Analyze(fontface->files[0], &is_supported, &file_type, &face_type, &face_num); + if (FAILED(hr)) + return hr; + + hr = IDWriteFactory7_CreateFontFace(fontface->factory, face_type, 1, fontface->files, fontface->index, + simulations, &face); + if (SUCCEEDED(hr)) + { + hr = IDWriteFontFace_QueryInterface(face, &IID_IDWriteFontFace3, (void **)ret); + IDWriteFontFace_Release(face); + } + + return hr; +} + +static BOOL WINAPI dwritefontface_reference_Equals(IDWriteFontFaceReference *iface, IDWriteFontFaceReference *ref) +{ + FIXME("%p, %p.\n", iface, ref); + + return E_NOTIMPL; +} + +static UINT32 WINAPI dwritefontface_reference_GetFontFaceIndex(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + + TRACE("%p.\n", iface); + + return fontface->index; +} + +static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_reference_GetSimulations(IDWriteFontFaceReference *iface) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + + TRACE("%p.\n", iface); + + return fontface->simulations; +} + +static HRESULT WINAPI dwritefontface_reference_GetFontFile(IDWriteFontFaceReference *iface, IDWriteFontFile **file) +{ + struct dwrite_fontface *fontface = impl_from_IDWriteFontFaceReference(iface); + + TRACE("%p, %p.\n", iface, file); + + *file = fontface->files[0]; + IDWriteFontFile_AddRef(*file); + + return S_OK; +} + +static UINT64 WINAPI dwritefontface_reference_GetLocalFileSize(IDWriteFontFaceReference *iface) +{ + FIXME("%p.\n", iface); + + return 0; +} + +static UINT64 WINAPI dwritefontface_reference_GetFileSize(IDWriteFontFaceReference *iface) +{ + FIXME("%p.\n", iface); + + return 0; +} + +static HRESULT WINAPI dwritefontface_reference_GetFileTime(IDWriteFontFaceReference *iface, FILETIME *writetime) +{ + FIXME("%p, %p.\n", iface, writetime); + + return E_NOTIMPL; +} + +static DWRITE_LOCALITY WINAPI dwritefontface_reference_GetLocality(IDWriteFontFaceReference *iface) +{ + FIXME("%p.\n", iface); + + return DWRITE_LOCALITY_LOCAL; +} + +static HRESULT WINAPI dwritefontface_reference_EnqueueFontDownloadRequest(IDWriteFontFaceReference *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontface_reference_EnqueueCharacterDownloadRequest(IDWriteFontFaceReference *iface, + WCHAR const *chars, UINT32 count) +{ + FIXME("%p, %s, %u.\n", iface, debugstr_wn(chars, count), count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontface_reference_EnqueueGlyphDownloadRequest(IDWriteFontFaceReference *iface, + UINT16 const *glyphs, UINT32 count) +{ + FIXME("%p, %p, %u.\n", iface, glyphs, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dwritefontface_reference_EnqueueFileFragmentDownloadRequest(IDWriteFontFaceReference *iface, + UINT64 offset, UINT64 size) +{ + FIXME("%p, 0x%s, 0x%s.\n", iface, wine_dbgstr_longlong(offset), wine_dbgstr_longlong(size)); + + return E_NOTIMPL; +} + +static const IDWriteFontFaceReferenceVtbl dwritefontface_reference_vtbl = +{ + dwritefontface_reference_QueryInterface, + dwritefontface_reference_AddRef, + dwritefontface_reference_Release, + dwritefontface_reference_CreateFontFace, + dwritefontface_reference_CreateFontFaceWithSimulations, + dwritefontface_reference_Equals, + dwritefontface_reference_GetFontFaceIndex, + dwritefontface_reference_GetSimulations, + dwritefontface_reference_GetFontFile, + dwritefontface_reference_GetLocalFileSize, + dwritefontface_reference_GetFileSize, + dwritefontface_reference_GetFileTime, + dwritefontface_reference_GetLocality, + dwritefontface_reference_EnqueueFontDownloadRequest, + dwritefontface_reference_EnqueueCharacterDownloadRequest, + dwritefontface_reference_EnqueueGlyphDownloadRequest, + dwritefontface_reference_EnqueueFileFragmentDownloadRequest, +}; + static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace5 **fontface) { struct dwrite_font_data *data = font->data; @@ -4677,6 +4871,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li }
fontface->IDWriteFontFace5_iface.lpVtbl = &dwritefontfacevtbl; + fontface->IDWriteFontFaceReference_iface.lpVtbl = &dwritefontface_reference_vtbl; fontface->refcount = 1; fontface->type = desc->face_type; fontface->file_count = desc->files_number; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index cdc41ec5a1..bee0ef5b0f 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -7775,9 +7775,8 @@ static void test_HasCharacter(void)
static void test_CreateFontFaceReference(void) { - static const WCHAR dummyW[] = {'d','u','m','m','y',0}; + IDWriteFontFaceReference *ref, *ref1, *ref3; IDWriteFontFace3 *fontface, *fontface1; - IDWriteFontFaceReference *ref, *ref1; IDWriteFontCollection1 *collection; IDWriteFontFile *file, *file1; IDWriteFactory3 *factory; @@ -7821,7 +7820,7 @@ todo_wine IDWriteFontFaceReference_Release(ref);
/* path however has to be valid */ - hr = IDWriteFactory3_CreateFontFaceReference(factory, dummyW, NULL, 0, DWRITE_FONT_SIMULATIONS_NONE, &ref); + hr = IDWriteFactory3_CreateFontFaceReference(factory, L"dummy", NULL, 0, DWRITE_FONT_SIMULATIONS_NONE, &ref); todo_wine ok(hr == DWRITE_E_FILENOTFOUND, "got 0x%08x\n", hr); if (hr == S_OK) @@ -7939,34 +7938,29 @@ todo_wine IDWriteFontFaceReference_Release(ref1);
hr = IDWriteFontFace3_GetFontFaceReference(fontface, &ref); - todo_wine ok(hr == S_OK, "Failed to get a reference, hr %#x.\n", hr); + EXPECT_REF(fontface, 2);
hr = IDWriteFontFace3_GetFontFaceReference(fontface, &ref1); - todo_wine ok(hr == S_OK, "Failed to get a reference, hr %#x.\n", hr); - if (hr == S_OK) ok(ref == ref1, "Unexpected reference %p, %p.\n", ref1, ref); + EXPECT_REF(fontface, 3); + + hr = IDWriteFontFace3_QueryInterface(fontface, &IID_IDWriteFontFaceReference, (void **)&ref3); + ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); + ok(ref == ref3, "Unexpected reference %p.\n", ref3); + + IDWriteFontFaceReference_Release(ref3);
- if (hr == S_OK) { hr = IDWriteFontFaceReference_CreateFontFace(ref, &fontface1); ok(hr == S_OK, "Failed to create fontface, hr %#x.\n", hr); ok(fontface1 == fontface, "Unexpected fontface %p, %p.\n", fontface1, fontface); IDWriteFontFace3_Release(fontface1);
- if (SUCCEEDED(hr = IDWriteFontFaceReference_QueryInterface(ref, &IID_IDWriteFontFaceReference1, - (void **)&ref2))) - { - UINT32 axis_count = IDWriteFontFaceReference1_GetFontAxisValueCount(ref2); - ok(!axis_count, "Unexpected axis value count.\n"); - IDWriteFontFaceReference1_Release(ref2); - } - IDWriteFontFaceReference_Release(ref); IDWriteFontFaceReference_Release(ref1); - } - IDWriteFontFace3_Release(fontface);
+ IDWriteFontFace3_Release(fontface); IDWriteFont3_Release(font3); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=64403
Your paranoid android.
=== w1064v1507 (32 bit report) ===
dwrite: font.c:7950: Test failed: Failed to get interface, hr 0x80004001. font.c:7951: Test failed: Unexpected reference 00000000. 0cd0:font: unhandled exception c0000005 at 0041F927
=== w1064v1507 (64 bit report) ===
dwrite: font.c:7950: Test failed: Failed to get interface, hr 0x80004001. font.c:7951: Test failed: Unexpected reference 0000000000000000. 0c9c:font: unhandled exception c0000005 at 000000000041CBAD