Aric Stewart : dwrite: Build non-system font collections as a list of font families.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Oct 9 13:14:34 CDT 2014


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Oct  8 09:52:07 2014 -0500

dwrite: Build non-system font collections as a list of font families.

---

 dlls/dwrite/font.c | 167 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 133 insertions(+), 34 deletions(-)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index a00b784..77121ec 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -55,6 +55,8 @@ struct dwrite_font_data {
 };
 
 struct dwrite_fontfamily_data {
+    LONG ref;
+
     IDWriteLocalizedStrings *familyname;
 
     struct dwrite_font_data **fonts;
@@ -69,6 +71,10 @@ struct dwrite_fontcollection {
     WCHAR **families;
     UINT32 count;
     int alloc;
+
+    struct dwrite_fontfamily_data **family_data;
+    DWORD data_count;
+    int data_alloc;
 };
 
 struct dwrite_fontfamily {
@@ -127,6 +133,7 @@ struct dwrite_fontfile {
 };
 
 static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFontFamily **family);
+static HRESULT create_fontfamily_from_data(struct dwrite_fontfamily_data *data, IDWriteFontCollection *collection, IDWriteFontFamily **family);
 static HRESULT create_font_base(IDWriteFont **font);
 static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFont **font);
 
@@ -201,6 +208,21 @@ static VOID _free_font_data(struct dwrite_font_data *data)
     heap_free(data);
 }
 
+static VOID _free_fontfamily_data(struct dwrite_fontfamily_data *data)
+{
+    int i;
+    if (!data)
+        return;
+    i = InterlockedDecrement(&data->ref);
+    if (i > 0)
+        return;
+    for (i = 0; i < data->font_count; i++)
+        _free_font_data(data->fonts[i]);
+    heap_free(data->fonts);
+    IDWriteLocalizedStrings_Release(data->familyname);
+    heap_free(data);
+}
+
 static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace *iface, REFIID riid, void **obj)
 {
     struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
@@ -746,15 +768,9 @@ static ULONG WINAPI dwritefontfamily_Release(IDWriteFontFamily *iface)
 
     if (!ref)
     {
-        int i;
-        IDWriteLocalizedStrings_Release(This->data->familyname);
-
         if (This->collection)
             IDWriteFontCollection_Release(This->collection);
-        for (i = 0; i < This->data->font_count; i++)
-            _free_font_data(This->data->fonts[i]);
-        heap_free(This->data->fonts);
-        heap_free(This->data);
+        _free_fontfamily_data(This->data);
         heap_free(This);
     }
 
@@ -909,6 +925,9 @@ static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection *iface)
         for (i = 0; i < This->count; i++)
             heap_free(This->families[i]);
         heap_free(This->families);
+        for (i = 0; i < This->data_count; i++)
+            _free_fontfamily_data(This->family_data[i]);
+        heap_free(This->family_data);
         heap_free(This);
     }
 
@@ -919,6 +938,8 @@ static UINT32 WINAPI dwritefontcollection_GetFontFamilyCount(IDWriteFontCollecti
 {
     struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection(iface);
     TRACE("(%p)\n", This);
+    if (This->data_count)
+        return This->data_count;
     return This->count;
 }
 
@@ -931,18 +952,31 @@ static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection *
 
     TRACE("(%p)->(%u %p)\n", This, index, family);
 
-    if (index >= This->count)
+    if (This->data_count)
     {
-        *family = NULL;
-        return E_FAIL;
+        if (index >= This->data_count)
+        {
+            *family = NULL;
+            return E_FAIL;
+        }
+        else
+            return create_fontfamily_from_data(This->family_data[index], iface, family);
     }
+    else
+    {
+        if (index >= This->count)
+        {
+            *family = NULL;
+            return E_FAIL;
+        }
 
-    hr = create_localizedstrings(&familyname);
-    if (FAILED(hr))
-        return hr;
-    add_localizedstring(familyname, enusW, This->families[index]);
+        hr = create_localizedstrings(&familyname);
+        if (FAILED(hr))
+            return hr;
+        add_localizedstring(familyname, enusW, This->families[index]);
 
-    return create_fontfamily(familyname, family);
+        return create_fontfamily(familyname, family);
+    }
 }
 
 static HRESULT WINAPI dwritefontcollection_FindFamilyName(IDWriteFontCollection *iface, const WCHAR *name, UINT32 *index, BOOL *exists)
@@ -952,16 +986,44 @@ static HRESULT WINAPI dwritefontcollection_FindFamilyName(IDWriteFontCollection
 
     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(name), index, exists);
 
-    for (i = 0; i < This->count; i++)
-        if (!strcmpW(This->families[i], name))
+    if (This->data_count)
+    {
+        for (i = 0; i < This->data_count; i++)
         {
-            *index = i;
-            *exists = TRUE;
-            return S_OK;
+            HRESULT hr;
+            IDWriteLocalizedStrings *family_name = This->family_data[i]->familyname;
+            int j;
+            for (j = 0; j < IDWriteLocalizedStrings_GetCount(family_name); j ++)
+            {
+                WCHAR buffer[255];
+                hr = IDWriteLocalizedStrings_GetString(family_name, j, buffer, 255);
+                if (SUCCEEDED(hr))
+                {
+                    if (!strcmpW(buffer, name))
+                    {
+                        *index = i;
+                        *exists = TRUE;
+                        return S_OK;
+                    }
+                }
+            }
         }
+        *index = (UINT32)-1;
+        *exists = FALSE;
+    }
+    else
+    {
+        for (i = 0; i < This->count; i++)
+            if (!strcmpW(This->families[i], name))
+            {
+                *index = i;
+                *exists = TRUE;
+                return S_OK;
+            }
 
-    *index = (UINT32)-1;
-    *exists = FALSE;
+        *index = (UINT32)-1;
+        *exists = FALSE;
+    }
 
     return S_OK;
 }
@@ -1023,6 +1085,20 @@ HRESULT get_system_fontcollection(IDWriteFontCollection **collection)
     This->alloc = 50;
     This->count = 0;
     This->families = heap_alloc(This->alloc*sizeof(WCHAR*));
+    if (!This->families)
+    {
+        heap_free(This);
+        return E_OUTOFMEMORY;
+    }
+    This->data_count = 0;
+    This->data_alloc = 2;
+    This->family_data = heap_alloc(sizeof(*This->family_data)*2);
+    if (!This->family_data)
+    {
+        heap_free(This->families);
+        heap_free(This);
+        return E_OUTOFMEMORY;
+    }
 
     TRACE("building system font collection:\n");
 
@@ -1039,7 +1115,7 @@ HRESULT get_system_fontcollection(IDWriteFontCollection **collection)
     return S_OK;
 }
 
-static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFontFamily **family)
+static HRESULT create_fontfamily_from_data(struct dwrite_fontfamily_data *data, IDWriteFontCollection *collection, IDWriteFontFamily **family)
 {
     struct dwrite_fontfamily *This;
 
@@ -1047,26 +1123,49 @@ static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFon
 
     This = heap_alloc(sizeof(struct dwrite_fontfamily));
     if (!This) return E_OUTOFMEMORY;
-    This->data = heap_alloc(sizeof(struct dwrite_fontfamily_data));
-    if (!This->data)
-    {
-        heap_free(This);
-        return E_OUTOFMEMORY;
-    }
 
     This->IDWriteFontFamily_iface.lpVtbl = &fontfamilyvtbl;
     This->ref = 1;
-    This->data->font_count = 0;
-    This->data->alloc = 2;
-    This->data->fonts = heap_alloc(sizeof(*This->data->fonts) * 2);
-    This->collection = NULL;
-    This->data->familyname = familyname;
+    This->collection = collection;
+    if (collection)
+        IDWriteFontCollection_AddRef(collection);
+    This->data = data;
+    InterlockedIncrement(&This->data->ref);
 
     *family = &This->IDWriteFontFamily_iface;
 
     return S_OK;
 }
 
+static HRESULT create_fontfamily(IDWriteLocalizedStrings *familyname, IDWriteFontFamily **family)
+{
+    struct dwrite_fontfamily_data *data;
+    HRESULT ret;
+
+    data = heap_alloc(sizeof(struct dwrite_fontfamily_data));
+    if (!data) return E_OUTOFMEMORY;
+
+    data->ref = 0;
+    data->font_count = 0;
+    data->alloc = 2;
+    data->fonts = heap_alloc(sizeof(*data->fonts) * 2);
+    if (!data->fonts)
+    {
+        heap_free(data);
+        return E_OUTOFMEMORY;
+    }
+    data->familyname = familyname;
+
+    ret = create_fontfamily_from_data(data, NULL, family);
+    if (FAILED(ret))
+    {
+        heap_free(data->fonts);
+        heap_free(data);
+    }
+
+    return ret;
+}
+
 static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFont **font)
 {
     struct dwrite_font *This;




More information about the wine-cvs mailing list