[PATCH 1/9] dwrite: Add partial implementation for IDWriteFontResource.

Nikolay Sivov nsivov at codeweavers.com
Thu Dec 5 02:55:57 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |   2 +
 dlls/dwrite/font.c           | 217 +++++++++++++++++++++++++++++++++++
 dlls/dwrite/main.c           |   4 +-
 dlls/dwrite/tests/font.c     |  22 ++--
 4 files changed, 233 insertions(+), 12 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 7898403dd9..a5d946c385 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -279,6 +279,8 @@ extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDD
 extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
 extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
 extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
+extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+        IDWriteFontResource **resource) DECLSPEC_HIDDEN;
 
 struct dwrite_fontface;
 
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 1bf88d6b17..8788181303 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -234,6 +234,16 @@ struct dwrite_fontfacereference
     IDWriteFactory5 *factory;
 };
 
+struct dwrite_fontresource
+{
+    IDWriteFontResource IDWriteFontResource_iface;
+    LONG refcount;
+
+    IDWriteFontFile *file;
+    UINT32 face_index;
+    IDWriteFactory7 *factory;
+};
+
 static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context)
 {
     struct dwrite_fontface *fontface = context;
@@ -325,6 +335,11 @@ static inline struct dwrite_fontfacereference *impl_from_IDWriteFontFaceReferenc
     return CONTAINING_RECORD(iface, struct dwrite_fontfacereference, IDWriteFontFaceReference1_iface);
 }
 
+static struct dwrite_fontresource *impl_from_IDWriteFontResource(IDWriteFontResource *iface)
+{
+    return CONTAINING_RECORD(iface, struct dwrite_fontresource, IDWriteFontResource_iface);
+}
+
 static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
 {
     static const DWRITE_GLYPH_METRICS nil;
@@ -6555,3 +6570,205 @@ HRESULT create_inmemory_fileloader(IDWriteFontFileLoader **ret)
 
     return S_OK;
 }
+
+static HRESULT WINAPI dwritefontresource_QueryInterface(IDWriteFontResource *iface, REFIID riid, void **obj)
+{
+    TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IDWriteFontResource) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IDWriteFontResource_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritefontresource_AddRef(IDWriteFontResource *iface)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+    ULONG refcount = InterlockedIncrement(&resource->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI dwritefontresource_Release(IDWriteFontResource *iface)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+    ULONG refcount = InterlockedDecrement(&resource->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    if (!refcount)
+    {
+        IDWriteFactory7_Release(resource->factory);
+        IDWriteFontFile_Release(resource->file);
+        heap_free(resource);
+    }
+
+    return refcount;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontFile(IDWriteFontResource *iface, IDWriteFontFile **fontfile)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+    TRACE("%p, %p.\n", iface, fontfile);
+
+    *fontfile = resource->file;
+    IDWriteFontFile_AddRef(*fontfile);
+
+    return S_OK;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontFaceIndex(IDWriteFontResource *iface)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+    TRACE("%p.\n", iface);
+
+    return resource->face_index;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontAxisCount(IDWriteFontResource *iface)
+{
+    FIXME("%p.\n", iface);
+
+    return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontResource *iface,
+        DWRITE_FONT_AXIS_VALUE const *values, UINT32 num_values)
+{
+    FIXME("%p, %p, %u.\n", iface, values, num_values);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontAxisRanges(IDWriteFontResource *iface,
+        DWRITE_FONT_AXIS_RANGE const *ranges, UINT32 num_ranges)
+{
+    FIXME("%p, %p, %u.\n", iface, ranges, num_ranges);
+
+    return E_NOTIMPL;
+}
+
+static DWRITE_FONT_AXIS_ATTRIBUTES WINAPI dwritefontresource_GetFontAxisAttributes(IDWriteFontResource *iface,
+        UINT32 axis)
+{
+    FIXME("%p, %u.\n", iface, axis);
+
+    return DWRITE_FONT_AXIS_ATTRIBUTES_NONE;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisNames(IDWriteFontResource *iface, UINT32 axis,
+        IDWriteLocalizedStrings **names)
+{
+    FIXME("%p, %u, %p.\n", iface, axis, names);
+
+    return E_NOTIMPL;
+}
+
+static UINT32 WINAPI dwritefontresource_GetAxisValueNameCount(IDWriteFontResource *iface, UINT32 axis)
+{
+    FIXME("%p, %u.\n", iface, axis);
+
+    return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisValueNames(IDWriteFontResource *iface, UINT32 axis,
+        UINT32 axis_value, DWRITE_FONT_AXIS_RANGE *axis_range, IDWriteLocalizedStrings **names)
+{
+    FIXME("%p, %u, %u, %p, %p.\n", iface, axis, axis_value, axis_range, names);
+
+    return E_NOTIMPL;
+}
+
+static BOOL WINAPI dwritefontresource_HasVariations(IDWriteFontResource *iface)
+{
+    FIXME("%p.\n", iface);
+
+    return FALSE;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFace(IDWriteFontResource *iface,
+        DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+        IDWriteFontFace5 **fontface)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+    IDWriteFontFaceReference1 *reference;
+    HRESULT hr;
+
+    TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, fontface);
+
+    hr = IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+            simulations, axis_values, num_values, &reference);
+    if (SUCCEEDED(hr))
+    {
+        hr = IDWriteFontFaceReference1_CreateFontFace(reference, fontface);
+        IDWriteFontFaceReference1_Release(reference);
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFaceReference(IDWriteFontResource *iface,
+        DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+        IDWriteFontFaceReference1 **reference)
+{
+    struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+    TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, reference);
+
+    return IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+            simulations, axis_values, num_values, reference);
+}
+
+static const IDWriteFontResourceVtbl fontresourcevtbl =
+{
+    dwritefontresource_QueryInterface,
+    dwritefontresource_AddRef,
+    dwritefontresource_Release,
+    dwritefontresource_GetFontFile,
+    dwritefontresource_GetFontFaceIndex,
+    dwritefontresource_GetFontAxisCount,
+    dwritefontresource_GetDefaultFontAxisValues,
+    dwritefontresource_GetFontAxisRanges,
+    dwritefontresource_GetFontAxisAttributes,
+    dwritefontresource_GetAxisNames,
+    dwritefontresource_GetAxisValueNameCount,
+    dwritefontresource_GetAxisValueNames,
+    dwritefontresource_HasVariations,
+    dwritefontresource_CreateFontFace,
+    dwritefontresource_CreateFontFaceReference,
+};
+
+HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+        IDWriteFontResource **ret)
+{
+    struct dwrite_fontresource *resource;
+
+    *ret = NULL;
+
+    resource = heap_alloc_zero(sizeof(*resource));
+    if (!resource)
+        return E_OUTOFMEMORY;
+
+    resource->IDWriteFontResource_iface.lpVtbl = &fontresourcevtbl;
+    resource->refcount = 1;
+    resource->face_index = face_index;
+    resource->file = file;
+    IDWriteFontFile_AddRef(resource->file);
+    resource->factory = factory;
+    IDWriteFactory7_AddRef(resource->factory);
+
+    *ret = &resource->IDWriteFontResource_iface;
+
+    return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 033a664dcf..1c1fabdb7d 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1666,9 +1666,9 @@ static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *if
 static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
         UINT32 face_index, IDWriteFontResource **resource)
 {
-    FIXME("%p, %p, %u, %p.\n", iface, file, face_index, resource);
+    TRACE("%p, %p, %u, %p.\n", iface, file, face_index, resource);
 
-    return E_NOTIMPL;
+    return create_font_resource(iface, file, face_index, resource);
 }
 
 static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 58f2af6e7a..f0266cb751 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9259,17 +9259,8 @@ static void test_font_resource(void)
     ok(hr == S_OK, "Failed to get file object, hr %#x.\n", hr);
 
     hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource);
-todo_wine
     ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
 
-    if (FAILED(hr))
-    {
-        IDWriteFactory6_Release(factory);
-        IDWriteFontFile_Release(fontfile);
-        IDWriteFontFace_Release(fontface);
-        return;
-    }
-
     hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource2);
     ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
     ok(resource != resource2, "Unexpected instance.\n");
@@ -9283,18 +9274,29 @@ todo_wine
     index = IDWriteFontResource_GetFontFaceIndex(resource);
     ok(!index, "Unexpected index %u.\n", index);
 
+    EXPECT_REF(resource, 1);
     hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference);
+todo_wine
     ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+    EXPECT_REF(resource, 1);
 
     hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference2);
+todo_wine
     ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+
+if (SUCCEEDED(hr))
+{
     ok(reference != reference2, "Unexpected reference instance.\n");
     IDWriteFontFaceReference1_Release(reference2);
     IDWriteFontFaceReference1_Release(reference);
-
+}
     hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
+todo_wine
     ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
 
+    if (FAILED(hr))
+        return;
+
     hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
     ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
     ok(resource != resource2, "Unexpected resource instance.\n");
-- 
2.24.0




More information about the wine-devel mailing list