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

This commit is contained in:
Aric Stewart 2014-10-08 09:52:07 -05:00 committed by Alexandre Julliard
parent cf7fa95980
commit 8a5707111a
1 changed files with 133 additions and 34 deletions

View File

@ -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,6 +952,18 @@ static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection *
TRACE("(%p)->(%u %p)\n", This, index, family);
if (This->data_count)
{
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;
@ -944,6 +977,7 @@ static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection *
return create_fontfamily(familyname, family);
}
}
static HRESULT WINAPI dwritefontcollection_FindFamilyName(IDWriteFontCollection *iface, const WCHAR *name, UINT32 *index, BOOL *exists)
{
@ -952,6 +986,33 @@ static HRESULT WINAPI dwritefontcollection_FindFamilyName(IDWriteFontCollection
TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(name), index, exists);
if (This->data_count)
{
for (i = 0; i < This->data_count; i++)
{
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))
{
@ -962,6 +1023,7 @@ static HRESULT WINAPI dwritefontcollection_FindFamilyName(IDWriteFontCollection
*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;