[v2 PATCH 2/2] dwrite: Implement GetFontFaceReference() for fontfaces.

Nikolay Sivov nsivov at codeweavers.com
Mon Feb 3 10:08:31 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

v2: fix test crashes on old Win10 builds.

 dlls/dwrite/dwrite_private.h |   1 +
 dlls/dwrite/font.c           | 203 ++++++++++++++++++++++++++++++++++-
 dlls/dwrite/tests/font.c     |  30 +++---
 3 files changed, 213 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..60c9b9c742 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,31 @@ 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 || broken(FAILED(hr)), "Failed to get interface, hr %#x.\n", hr);
+            if (SUCCEEDED(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);
         }
 
-- 
2.24.1




More information about the wine-devel mailing list