Signed-off-by: Nikolay Sivov nsivov@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");