Aric Stewart : dwrite: Implement a list of font data for IDWriteFontFamily.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Sep 4 14:48:40 CDT 2014


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Sep  3 13:11:35 2014 -0500

dwrite: Implement a list of font data for IDWriteFontFamily.

---

 dlls/dwrite/font.c | 119 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 99 insertions(+), 20 deletions(-)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 4088548..546dab8 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -137,6 +137,8 @@ struct dwrite_fontface_data {
 };
 
 struct dwrite_font_data {
+    LONG ref;
+
     DWRITE_FONT_STYLE style;
     DWRITE_FONT_STRETCH stretch;
     DWRITE_FONT_WEIGHT weight;
@@ -161,6 +163,10 @@ struct dwrite_fontfamily {
     IDWriteFontFamily IDWriteFontFamily_iface;
     LONG ref;
 
+    struct dwrite_font_data **fonts;
+    UINT32  font_count;
+    UINT32  alloc;
+
     WCHAR *familyname;
 };
 
@@ -209,6 +215,7 @@ struct dwrite_fontfile {
 
 static HRESULT create_fontfamily(const WCHAR *familyname, IDWriteFontFamily **family);
 static HRESULT create_font_base(IDWriteFont **font);
+static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFont **font);
 
 static inline struct dwrite_fontface *impl_from_IDWriteFontFace(IDWriteFontFace *iface)
 {
@@ -268,6 +275,19 @@ static VOID _free_fontface_data(struct dwrite_fontface_data *data)
     heap_free(data);
 }
 
+static VOID _free_font_data(struct dwrite_font_data *data)
+{
+    int i;
+    if (!data)
+        return;
+    i = InterlockedDecrement(&data->ref);
+    if (i > 0)
+        return;
+    _free_fontface_data(data->face_data);
+    heap_free(data->facename);
+    heap_free(data);
+}
+
 static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace *iface, REFIID riid, void **obj)
 {
     struct dwrite_fontface *This = impl_from_IDWriteFontFace(iface);
@@ -643,9 +663,7 @@ static ULONG WINAPI dwritefont_Release(IDWriteFont *iface)
     {
         if (This->face) IDWriteFontFace_Release(This->face);
         if (This->family) IDWriteFontFamily_Release(This->family);
-        heap_free(This->data->facename);
-        _free_fontface_data(This->data->face_data);
-        heap_free(This->data);
+        _free_font_data(This->data);
         heap_free(This);
     }
 
@@ -815,7 +833,12 @@ static ULONG WINAPI dwritefontfamily_Release(IDWriteFontFamily *iface)
 
     if (!ref)
     {
+        int i;
         heap_free(This->familyname);
+
+        for (i = 0; i < This->font_count; i++)
+            _free_font_data(This->fonts[i]);
+        heap_free(This->fonts);
         heap_free(This);
     }
 
@@ -832,15 +855,30 @@ static HRESULT WINAPI dwritefontfamily_GetFontCollection(IDWriteFontFamily *ifac
 static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily *iface)
 {
     struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
-    FIXME("(%p): stub\n", This);
-    return 0;
+    TRACE("(%p)\n", This);
+    return This->font_count;
 }
 
 static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily *iface, UINT32 index, IDWriteFont **font)
 {
     struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily(iface);
-    FIXME("(%p)->(%u %p): stub\n", This, index, font);
-    return E_NOTIMPL;
+    TRACE("(%p)->(%u %p)\n", This, index, font);
+    if (This->font_count > 0)
+    {
+        HRESULT hr;
+        if (index >= This->font_count)
+            return E_INVALIDARG;
+        hr = create_font_from_data(This->fonts[index], font);
+        if (SUCCEEDED(hr))
+        {
+            struct dwrite_font *font_data = impl_from_IDWriteFont(*font);
+            font_data->family = iface;
+            IDWriteFontFamily_AddRef(iface);
+        }
+        return hr;
+    }
+    else
+        return E_NOTIMPL;
 }
 
 static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily *iface, IDWriteLocalizedStrings **names)
@@ -865,12 +903,38 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily *i
 
     TRACE("(%p)->(%d %d %d %p)\n", This, weight, stretch, style, font);
 
-    memset(&lf, 0, sizeof(lf));
-    lf.lfWeight = weight;
-    lf.lfItalic = style == DWRITE_FONT_STYLE_ITALIC;
-    strcpyW(lf.lfFaceName, This->familyname);
+    /* fallback for system font collections */
+    if (This->font_count == 0)
+    {
+        memset(&lf, 0, sizeof(lf));
+        lf.lfWeight = weight;
+        lf.lfItalic = style == DWRITE_FONT_STYLE_ITALIC;
+        strcpyW(lf.lfFaceName, This->familyname);
 
-    return create_font_from_logfont(&lf, font);
+        return create_font_from_logfont(&lf, font);
+    }
+    else
+    {
+        int i;
+        for (i = 0; i < This->font_count; i++)
+        {
+            if (style == This->fonts[i]->style &&
+                weight == This->fonts[i]->weight &&
+                stretch == This->fonts[i]->stretch)
+            {
+                HRESULT hr;
+                hr = create_font_from_data(This->fonts[i], font);
+                if (SUCCEEDED(hr))
+                {
+                    struct dwrite_font *font_data = impl_from_IDWriteFont(*font);
+                    font_data->family = iface;
+                    IDWriteFontFamily_AddRef(iface);
+                }
+                return hr;
+            }
+        }
+        return DWRITE_E_NOFONT;
+    }
 }
 
 static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily *iface, DWRITE_FONT_WEIGHT weight,
@@ -1063,6 +1127,9 @@ static HRESULT create_fontfamily(const WCHAR *familyname, IDWriteFontFamily **fa
 
     This->IDWriteFontFamily_iface.lpVtbl = &fontfamilyvtbl;
     This->ref = 1;
+    This->font_count = 0;
+    This->alloc = 2;
+    This->fonts = heap_alloc(sizeof(*This->fonts) * 2);
     This->familyname = heap_strdupW(familyname);
 
     *family = &This->IDWriteFontFamily_iface;
@@ -1121,32 +1188,44 @@ static void get_font_properties(struct dwrite_font *font, HDC hdc)
     }
 }
 
-static HRESULT create_font_base(IDWriteFont **font)
+static HRESULT create_font_from_data(struct dwrite_font_data *data, IDWriteFont **font)
 {
     struct dwrite_font *This;
     *font = NULL;
 
     This = heap_alloc(sizeof(struct dwrite_font));
     if (!This) return E_OUTOFMEMORY;
-    This->data = heap_alloc(sizeof(struct dwrite_font_data));
-    if (!This->data)
-    {
-        heap_free(This);
-        return E_OUTOFMEMORY;
-    }
 
     This->IDWriteFont_iface.lpVtbl = &dwritefontvtbl;
     This->ref = 1;
-    This->data->face_data = NULL;
     This->face = NULL;
     This->family = NULL;
     This->is_system = FALSE;
+    This->data = data;
+    InterlockedIncrement(&This->data->ref);
 
     *font = &This->IDWriteFont_iface;
 
     return S_OK;
 }
 
+static HRESULT create_font_base(IDWriteFont **font)
+{
+    struct dwrite_font_data *data;
+    HRESULT ret;
+
+    *font = NULL;
+    data = heap_alloc(sizeof(*data));
+    if (!data) return E_OUTOFMEMORY;
+
+    data->ref = 0;
+    data->face_data = NULL;
+
+    ret = create_font_from_data( data, font );
+    if (FAILED(ret)) heap_free( data );
+    return ret;
+}
+
 HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font)
 {
     const WCHAR* facename, *familyname;




More information about the wine-cvs mailing list