Nikolay Sivov : dwrite: Add all installed font families to system font collection.

Alexandre Julliard julliard at winehq.org
Mon Oct 22 13:42:45 CDT 2012


Module: wine
Branch: master
Commit: f0f1735495d79c474f50c0303718b719a4febe2d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f0f1735495d79c474f50c0303718b719a4febe2d

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Oct 21 00:24:35 2012 -0400

dwrite: Add all installed font families to system font collection.

---

 dlls/dwrite/dwrite_private.h |    2 +-
 dlls/dwrite/font.c           |   57 +++++++++++++++++++++++++++++++++++++++--
 dlls/dwrite/main.c           |    8 ++++-
 dlls/dwrite/tests/font.c     |   34 ++++++++++++++++++++++++-
 4 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 3135ade..4cb0e3b 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 d5346c9..689a330 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 5f69723..4605008 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 594ccea..9dc59e0 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);
 }




More information about the wine-cvs mailing list