Module: wine Branch: master Commit: 8a5707111a5ecda83374fd9e82f305518b55d976 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8a5707111a5ecda83374fd9e82...
Author: Aric Stewart aric@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;