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