diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 3135adee4e9..4cb0e3beb22 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -68,10 +68,10 @@ static inline LPWSTR heap_strdupnW(const WCHAR *str, UINT32 len) } extern HRESULT create_font_from_logfont(const LOGFONTW*, IDWriteFont**) DECLSPEC_HIDDEN; -extern HRESULT create_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN; extern HRESULT create_textformat(const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH, FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN; extern HRESULT create_textlayout(const WCHAR*,UINT32,IDWriteTextLayout**) DECLSPEC_HIDDEN; extern HRESULT create_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN; extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; +extern HRESULT create_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index d5346c95d4b..689a3301ff2 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -130,6 +130,10 @@ typedef struct struct dwrite_fontcollection { IDWriteFontCollection IDWriteFontCollection_iface; LONG ref; + + WCHAR **families; + UINT32 count; + int alloc; }; struct dwrite_fontfamily { @@ -657,7 +661,14 @@ static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface) TRACE("(%p)->(%d)\n", This, ref); if (!ref) + { + int i; + + for (i = 0; i < This->count; i++) + heap_free(This->families[i]); + heap_free(This->families); heap_free(This); + } return ref; } @@ -665,8 +676,8 @@ static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface) static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface) { struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface); - FIXME("(%p): stub\n", This); - return 0; + TRACE("(%p)\n", This); + return This->count; } static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection *iface, UINT32 index, IDWriteFontFamily **family) @@ -700,9 +711,35 @@ static const IDWriteFontCollectionVtbl fontcollectionvtbl = { dwritefontcollection_GetFontFromFontFace }; -HRESULT create_fontcollection(IDWriteFontCollection **collection) +static HRESULT add_family_syscollection(struct dwrite_fontcollection *collection, const WCHAR *family) +{ + /* check for duplicate family name */ + if (collection->count && !strcmpW(collection->families[collection->count-1], family)) return S_OK; + + /* double array length */ + if (collection->count == collection->alloc) + { + collection->alloc *= 2; + collection->families = heap_realloc(collection->families, collection->alloc*sizeof(WCHAR*)); + } + + collection->families[collection->count++] = heap_strdupW(family); + TRACE("family name %s\n", debugstr_w(family)); + + return S_OK; +} + +static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lParam) +{ + struct dwrite_fontcollection *collection = (struct dwrite_fontcollection*)lParam; + return add_family_syscollection(collection, lf->lfFaceName) == S_OK; +} + +HRESULT create_system_fontcollection(IDWriteFontCollection **collection) { struct dwrite_fontcollection *This; + LOGFONTW lf; + HDC hdc; *collection = NULL; @@ -712,6 +749,20 @@ HRESULT create_fontcollection(IDWriteFontCollection **collection) This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl; This->ref = 1; + This->alloc = 50; + This->count = 0; + This->families = heap_alloc(This->alloc*sizeof(WCHAR*)); + + TRACE("building system font collection:\n"); + + hdc = CreateCompatibleDC(0); + memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = DEFAULT_PITCH; + lf.lfFaceName[0] = 0; + EnumFontFamiliesExW(hdc, &lf, enum_font_families, (LPARAM)This, 0); + DeleteDC(hdc); + *collection = &This->IDWriteFontCollection_iface; return S_OK; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 5f69723f96a..46050082db9 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -384,8 +384,12 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface) static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *iface, IDWriteFontCollection **collection, BOOL check_for_updates) { - FIXME("(%p %d): semi-stub\n", collection, check_for_updates); - return create_fontcollection(collection); + TRACE("(%p %d)\n", collection, check_for_updates); + + if (check_for_updates) + FIXME("checking for system font updates not implemented\n"); + + return create_system_fontcollection(collection); } static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface, diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 594ccea081c..9dc59e05f10 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -41,11 +41,11 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) static IDWriteFactory *factory; static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0}; +static const WCHAR blahW[] = {'B','l','a','h','!',0}; static void test_CreateFontFromLOGFONT(void) { static const WCHAR tahomaspW[] = {'T','a','h','o','m','a',' ',0}; - static const WCHAR blahW[] = {'B','l','a','h','!',0}; IDWriteGdiInterop *interop; DWRITE_FONT_WEIGHT weight; DWRITE_FONT_STYLE style; @@ -523,6 +523,37 @@ todo_wine IDWriteGdiInterop_Release(interop); } +static void test_system_fontcollection(void) +{ + IDWriteFontCollection *collection; + HRESULT hr; + UINT32 i; + BOOL ret; + + hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + i = IDWriteFontCollection_GetFontFamilyCount(collection); + ok(i, "got %u\n", i); + +todo_wine { + ret = FALSE; + i = (UINT32)-1; + hr = IDWriteFontCollection_FindFamilyName(collection, tahomaW, &i, &ret); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(ret, "got %d\n", ret); + ok(i != (UINT32)-1, "got %u\n", i); + + ret = TRUE; + i = 0; + hr = IDWriteFontCollection_FindFamilyName(collection, blahW, &i, &ret); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!ret, "got %d\n", ret); + ok(i == (UINT32)-1, "got %u\n", i); +} + IDWriteFontCollection_Release(collection); +} + START_TEST(font) { HRESULT hr; @@ -541,6 +572,7 @@ START_TEST(font) test_GetFamilyNames(); test_CreateFontFace(); test_GetMetrics(); + test_system_fontcollection(); IDWriteFactory_Release(factory); }