Signed-off-by: Nikolay Sivov <nsivov(a)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