For React Native.
-- v2: dwrite: Implement dwritefactory3_GetFontDownloadQueue(). dwrite: Add IDWriteFontDownloadQueue tests.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dwrite/tests/font.c | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 362b87aa968..ce65382d0c4 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -10493,6 +10493,53 @@ static void test_GetMatchingFontsByLOGFONT(void) ok(!refcount, "Factory wasn't released, %lu.\n", refcount); }
+static void test_font_download_queue(void) +{ + IDWriteFontDownloadQueue *queue, *queue2; + IDWriteFactory3 *factory; + BOOL is_empty; + UINT64 count; + HRESULT hr; + ULONG ref; + + factory = create_factory_iid(&IID_IDWriteFactory3); + if (!factory) + { + win_skip("GetFontDownloadQueue() is not supported\n"); + return; + } + + EXPECT_REF(factory, 1); + hr = IDWriteFactory3_GetFontDownloadQueue(factory, &queue); + todo_wine + ok(hr == S_OK, "got %#lx\n", hr); + if (FAILED(hr)) + { + IDWriteFactory3_Release(factory); + return; + } + EXPECT_REF(queue, 1); + EXPECT_REF(factory, 2); + + hr = IDWriteFactory3_GetFontDownloadQueue(factory, &queue2); + ok(hr == S_OK, "got %#lx\n", hr); + ok(queue == queue2, "Got unexpected object\n"); + EXPECT_REF(queue, 2); + EXPECT_REF(factory, 2); + IDWriteFontDownloadQueue_Release(queue2); + + is_empty = IDWriteFontDownloadQueue_IsEmpty(queue); + ok(is_empty, "Expected empty queue\n"); + + count = IDWriteFontDownloadQueue_GetGenerationCount(queue); + ok(count == 0, "Got unexpected generation count %I64u\n", count); + + ref = IDWriteFontDownloadQueue_Release(queue); + ok(ref == 0, "font download queue not released, %lu\n", ref); + ref = IDWriteFactory3_Release(factory); + ok(ref == 0, "factory not released, %lu\n", ref); +} + START_TEST(font) { IDWriteFactory *factory; @@ -10568,6 +10615,7 @@ START_TEST(font) test_system_font_set(); test_CreateFontCollectionFromFontSet(); test_GetMatchingFontsByLOGFONT(); + test_font_download_queue();
IDWriteFactory_Release(factory); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dwrite/main.c | 154 ++++++++++++++++++++++++++++++++++++++- dlls/dwrite/tests/font.c | 6 -- 2 files changed, 152 insertions(+), 8 deletions(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 1dc5ae48baa..ec03027655b 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -601,6 +601,7 @@ struct dwritefactory IDWriteFontCollection1 *eudc_collection; IDWriteGdiInterop1 *gdiinterop; IDWriteFontFallback1 *fallback; + IDWriteFontDownloadQueue *download_queue;
IDWriteFontFileLoader *localfontfileloader; struct list localfontfaces; @@ -1705,13 +1706,162 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory7 *if &IID_IDWriteFontCollection1, (void **)collection); }
-static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue) +struct font_download_queue +{ + IDWriteFontDownloadQueue IDWriteFontDownloadQueue_iface; + LONG refcount; + IDWriteFactory7 *factory; +}; + +static inline struct font_download_queue *impl_from_IDWriteFontDownloadQueue(IDWriteFontDownloadQueue *iface) +{ + return CONTAINING_RECORD(iface, struct font_download_queue, IDWriteFontDownloadQueue_iface); +} + +static HRESULT WINAPI font_download_queue_QueryInterface(IDWriteFontDownloadQueue *iface, + REFIID iid, void **out) +{ + struct font_download_queue *impl = impl_from_IDWriteFontDownloadQueue(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IDWriteFontDownloadQueue)) + { + *out = &impl->IDWriteFontDownloadQueue_iface; + IDWriteFontDownloadQueue_AddRef(&impl->IDWriteFontDownloadQueue_iface); + return S_OK; + } + + *out = NULL; + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI font_download_queue_AddRef(IDWriteFontDownloadQueue *iface) +{ + struct font_download_queue *impl = impl_from_IDWriteFontDownloadQueue(iface); + ULONG ref = InterlockedIncrement(&impl->refcount); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI font_download_queue_Release(IDWriteFontDownloadQueue *iface) +{ + struct font_download_queue *impl = impl_from_IDWriteFontDownloadQueue(iface); + struct dwritefactory *factory = impl_from_IDWriteFactory7(impl->factory); + ULONG ref = InterlockedDecrement(&impl->refcount); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + { + EnterCriticalSection(&factory->cs); + factory->download_queue = NULL; + LeaveCriticalSection(&factory->cs); + IDWriteFactory7_Release(impl->factory); + free(impl); + } + return ref; +} + +static HRESULT WINAPI font_download_queue_AddListener(IDWriteFontDownloadQueue *iface, + IDWriteFontDownloadListener *listener, UINT32 *token) +{ + FIXME("%p, %p, %p stub!\n", iface, listener, token); + return E_NOTIMPL; +} + +static HRESULT WINAPI font_download_queue_RemoveListener(IDWriteFontDownloadQueue *iface, UINT32 token) +{ + FIXME("%p, %#x stub!\n", iface, token); + return E_NOTIMPL; +} + +static BOOL WINAPI font_download_queue_IsEmpty(IDWriteFontDownloadQueue *iface) { - FIXME("%p, %p: stub\n", iface, queue); + FIXME("%p stub!\n", iface); + return TRUE; +}
+static HRESULT WINAPI font_download_queue_BeginDownload(IDWriteFontDownloadQueue *iface, IUnknown *context) +{ + FIXME("%p, %p stub!\n", iface, context); return E_NOTIMPL; }
+static HRESULT WINAPI font_download_queue_CancelDownload(IDWriteFontDownloadQueue *iface) +{ + FIXME("%p stub!\n", iface); + return E_NOTIMPL; +} + +static UINT64 WINAPI font_download_queue_GetGenerationCount(IDWriteFontDownloadQueue *iface) +{ + FIXME("%p stub!\n", iface); + return 0; +} + +static const struct IDWriteFontDownloadQueueVtbl font_download_queue_vtbl = +{ + font_download_queue_QueryInterface, + font_download_queue_AddRef, + font_download_queue_Release, + /* IDWriteFontDownloadQueue methods */ + font_download_queue_AddListener, + font_download_queue_RemoveListener, + font_download_queue_IsEmpty, + font_download_queue_BeginDownload, + font_download_queue_CancelDownload, + font_download_queue_GetGenerationCount, +}; + +static HRESULT create_font_download_queue(IDWriteFactory7 *factory) +{ + struct dwritefactory *dwritefactory = impl_from_IDWriteFactory7(factory); + struct font_download_queue *impl; + + if (!(impl = calloc(1, sizeof(*impl)))) + return E_OUTOFMEMORY; + + impl->IDWriteFontDownloadQueue_iface.lpVtbl = &font_download_queue_vtbl; + impl->refcount = 1; + impl->factory = factory; + IDWriteFactory7_AddRef(impl->factory); + dwritefactory->download_queue = &impl->IDWriteFontDownloadQueue_iface; + return S_OK; +} + +static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue) +{ + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); + + TRACE("%p, %p.\n", iface, queue); + + *queue = NULL; + + EnterCriticalSection(&factory->cs); + if (!factory->download_queue) + { + HRESULT hr = create_font_download_queue(iface); + if (FAILED(hr)) + { + LeaveCriticalSection(&factory->cs); + return hr; + } + + *queue = factory->download_queue; + } + else + { + *queue = factory->download_queue; + IDWriteFontDownloadQueue_AddRef(*queue); + } + + LeaveCriticalSection(&factory->cs); + return S_OK; +} + static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *iface, D2D1_POINT_2F origin, DWRITE_GLYPH_RUN const *run, DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc, DWRITE_GLYPH_IMAGE_FORMATS desired_formats, DWRITE_MEASURING_MODE measuring_mode, DWRITE_MATRIX const *transform, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index ce65382d0c4..0cd5fefb508 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -10511,13 +10511,7 @@ static void test_font_download_queue(void)
EXPECT_REF(factory, 1); hr = IDWriteFactory3_GetFontDownloadQueue(factory, &queue); - todo_wine ok(hr == S_OK, "got %#lx\n", hr); - if (FAILED(hr)) - { - IDWriteFactory3_Release(factory); - return; - } EXPECT_REF(queue, 1); EXPECT_REF(factory, 2);
Nikolay Sivov (@nsivov) commented about dlls/dwrite/main.c:
&IID_IDWriteFontCollection1, (void **)collection);
}
-static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue) +struct font_download_queue +{
- IDWriteFontDownloadQueue IDWriteFontDownloadQueue_iface;
- LONG refcount;
- IDWriteFactory7 *factory;
+};
For simplicity let's just add IDWriteFontDownloadQueue_iface field to the factory structure directly.
Nikolay Sivov (@nsivov) commented about dlls/dwrite/main.c:
REFIID iid, void **out)
+{
- struct font_download_queue *impl = impl_from_IDWriteFontDownloadQueue(iface);
- TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_IUnknown)
|| IsEqualGUID(iid, &IID_IDWriteFontDownloadQueue))
- {
*out = &impl->IDWriteFontDownloadQueue_iface;
IDWriteFontDownloadQueue_AddRef(&impl->IDWriteFontDownloadQueue_iface);
return S_OK;
- }
- *out = NULL;
- FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
WARN() is enough.
Nikolay Sivov (@nsivov) commented about dlls/dwrite/tests/font.c:
- UINT64 count;
- HRESULT hr;
- ULONG ref;
- factory = create_factory_iid(&IID_IDWriteFactory3);
- if (!factory)
- {
win_skip("GetFontDownloadQueue() is not supported\n");
return;
- }
- EXPECT_REF(factory, 1);
- hr = IDWriteFactory3_GetFontDownloadQueue(factory, &queue);
- ok(hr == S_OK, "got %#lx\n", hr);
- EXPECT_REF(queue, 1);
- EXPECT_REF(factory, 2);
I'd say this is implementation details that we don't need to follow. What makes sense is to create two factories and test that queue instances are different, since it's visible to listeners.