Aric Stewart : dwrite: Add the system font collection to the dwrite factory object.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Sep 2 14:30:38 CDT 2014


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue Sep  2 07:17:57 2014 -0500

dwrite: Add the system font collection to the dwrite factory object.

---

 dlls/dwrite/dwrite_private.h |  1 -
 dlls/dwrite/font.c           | 95 ++++++++++++++++++++------------------------
 dlls/dwrite/layout.c         | 11 +----
 dlls/dwrite/main.c           | 28 ++++++++++---
 4 files changed, 69 insertions(+), 66 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 8fda71e..e78f9bf 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -92,7 +92,6 @@ extern HRESULT get_gdiinterop(IDWriteGdiInterop**) DECLSPEC_HIDDEN;
 extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
 extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
 extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN;
-extern void release_system_fontcollection(void) DECLSPEC_HIDDEN;
 extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
 extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
 extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index c835ff4..5be7c83 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -127,14 +127,13 @@ typedef struct
 
 struct dwrite_fontcollection {
     IDWriteFontCollection IDWriteFontCollection_iface;
+    LONG ref;
 
     WCHAR **families;
     UINT32 count;
     int alloc;
 };
 
-static IDWriteFontCollection *system_collection;
-
 struct dwrite_fontfamily {
     IDWriteFontFamily IDWriteFontFamily_iface;
     LONG ref;
@@ -844,14 +843,30 @@ static HRESULT WINAPI dwritefontcollection_QueryInterface(IDWriteFontCollection
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI dwritesysfontcollection_AddRef(IDWriteFontCollection *iface)
+static ULONG WINAPI dwritefontcollection_AddRef(IDWriteFontCollection *iface)
 {
-    return 2;
+    struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+    TRACE("(%p)->(%d)\n", This, ref);
+    return ref;
 }
 
-static ULONG WINAPI dwritesysfontcollection_Release(IDWriteFontCollection *iface)
+static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface)
 {
-    return 1;
+    unsigned int i;
+    struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+    TRACE("(%p)->(%d)\n", This, ref);
+
+    if (!ref)
+    {
+        for (i = 0; i < This->count; i++)
+            heap_free(This->families[i]);
+        heap_free(This->families);
+        heap_free(This);
+    }
+
+    return ref;
 }
 
 static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollection *iface)
@@ -904,10 +919,10 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
     return E_NOTIMPL;
 }
 
-static const IDWriteFontCollectionVtbl systemfontcollectionvtbl = {
+static const IDWriteFontCollectionVtbl fontcollectionvtbl = {
     dwritefontcollection_QueryInterface,
-    dwritesysfontcollection_AddRef,
-    dwritesysfontcollection_Release,
+    dwritefontcollection_AddRef,
+    dwritefontcollection_Release,
     dwritefontcollection_GetFontFamilyCount,
     dwritefontcollection_GetFontFamily,
     dwritefontcollection_FindFamilyName,
@@ -938,56 +953,34 @@ static INT CALLBACK enum_font_families(const LOGFONTW *lf, const TEXTMETRICW *tm
     return add_family_syscollection(collection, lf->lfFaceName) == S_OK;
 }
 
-static void release_font_collection(IDWriteFontCollection *iface)
-{
-    struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
-    unsigned int i;
-
-    for (i = 0; i < This->count; i++)
-        heap_free(This->families[i]);
-    heap_free(This->families);
-    heap_free(This);
-}
-
-void release_system_fontcollection(void)
-{
-    if (system_collection)
-        release_font_collection(system_collection);
-}
-
 HRESULT get_system_fontcollection(IDWriteFontCollection **collection)
 {
-    if (!system_collection)
-    {
-        struct dwrite_fontcollection *This;
-        LOGFONTW lf;
-        HDC hdc;
-
-        *collection = NULL;
+    struct dwrite_fontcollection *This;
+    LOGFONTW lf;
+    HDC hdc;
 
-        This = heap_alloc(sizeof(struct dwrite_fontcollection));
-        if (!This) return E_OUTOFMEMORY;
+    *collection = NULL;
 
-        This->IDWriteFontCollection_iface.lpVtbl = &systemfontcollectionvtbl;
-        This->alloc = 50;
-        This->count = 0;
-        This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
+    This = heap_alloc(sizeof(struct dwrite_fontcollection));
+    if (!This) return E_OUTOFMEMORY;
 
-        TRACE("building system font collection:\n");
+    This->IDWriteFontCollection_iface.lpVtbl = &fontcollectionvtbl;
+    This->ref = 1;
+    This->alloc = 50;
+    This->count = 0;
+    This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
 
-        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);
+    TRACE("building system font collection:\n");
 
-        if (InterlockedCompareExchangePointer((void**)&system_collection, &This->IDWriteFontCollection_iface, NULL))
-            release_font_collection(&This->IDWriteFontCollection_iface);
-    }
+    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 = system_collection;
+    *collection = &This->IDWriteFontCollection_iface;
 
     return S_OK;
 }
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index a2da73b..82525d8 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -229,7 +229,7 @@ static struct layout_range *alloc_layout_range(struct dwrite_textlayout *layout,
     range->strikethrough = FALSE;
     range->collection = layout->format.collection;
     if (range->collection)
-        IDWriteFontCollection_Release(range->collection);
+        IDWriteFontCollection_AddRef(range->collection);
 
     return range;
 }
@@ -1781,14 +1781,7 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle
         IDWriteFontCollection_AddRef(collection);
     }
     else
-    {
-        HRESULT hr = get_system_fontcollection(&This->format.collection);
-        if (hr != S_OK)
-        {
-            IDWriteTextFormat_Release(&This->IDWriteTextFormat_iface);
-            return hr;
-        }
-    }
+        ERR("Collection should always be set\n");
 
     *format = &This->IDWriteTextFormat_iface;
 
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 83f705b..01394dc 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -43,10 +43,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls( hinstDLL );
         break;
-    case DLL_PROCESS_DETACH:
-        if (reserved) break;
-        release_system_fontcollection();
-        break;
     }
     return TRUE;
 }
@@ -364,6 +360,7 @@ struct dwritefactory{
     LONG ref;
 
     IDWriteLocalFontFileLoader* localfontfileloader;
+    IDWriteFontCollection *system_collection;
 
     IDWriteFontCollectionLoader **loaders;
     LONG loader_count;
@@ -422,6 +419,8 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface)
             if (This->file_loaders[i])
                 IDWriteFontFileLoader_Release(This->file_loaders[i]);
         heap_free(This->file_loaders);
+        if (This->system_collection)
+            IDWriteFontCollection_Release(This->system_collection);
         heap_free(This);
     }
 
@@ -431,13 +430,22 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory *iface)
 static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory *iface,
     IDWriteFontCollection **collection, BOOL check_for_updates)
 {
+    HRESULT hr = S_OK;
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
     TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates);
 
     if (check_for_updates)
         FIXME("checking for system font updates not implemented\n");
 
-    return get_system_fontcollection(collection);
+    if (!This->system_collection)
+        hr = get_system_fontcollection(&This->system_collection);
+
+    if (SUCCEEDED(hr))
+        IDWriteFontCollection_AddRef(This->system_collection);
+
+    *collection = This->system_collection;
+
+    return hr;
 }
 
 static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory *iface,
@@ -642,6 +650,15 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory *iface, WCHA
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
     TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This, debugstr_w(family_name), collection, weight, style, stretch,
         size, debugstr_w(locale), format);
+
+    if (!collection)
+    {
+        HRESULT hr = IDWriteFactory_GetSystemFontCollection(iface, &collection, FALSE);
+        if (hr != S_OK)
+            return hr;
+        /* Our ref count is 1 too many, since we will add ref in create_textformat */
+        IDWriteFontCollection_Release(This->system_collection);
+    }
     return create_textformat(family_name, collection, weight, style, stretch, size, locale, format);
 }
 
@@ -759,6 +776,7 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno
     This->loaders = heap_alloc_zero(sizeof(*This->loaders) * 2);
     This->file_loader_count = 2;
     This->file_loaders = heap_alloc_zero(sizeof(*This->file_loaders) * 2);
+    This->system_collection = NULL;
 
     *factory = (IUnknown*)&This->IDWriteFactory_iface;
 




More information about the wine-cvs mailing list