mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 12:47:44 +00:00
dwrite: Improve font objects refcounting.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6a307598b1
commit
be5a4656bd
5 changed files with 617 additions and 215 deletions
|
@ -118,12 +118,6 @@ static inline BOOL is_simulation_valid(DWRITE_FONT_SIMULATIONS simulations)
|
|||
DWRITE_FONT_SIMULATIONS_OBLIQUE)) == 0;
|
||||
}
|
||||
|
||||
struct gdiinterop
|
||||
{
|
||||
IDWriteGdiInterop1 IDWriteGdiInterop1_iface;
|
||||
IDWriteFactory4 *factory;
|
||||
};
|
||||
|
||||
struct textlayout_desc
|
||||
{
|
||||
IDWriteFactory4 *factory;
|
||||
|
@ -169,7 +163,6 @@ extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT
|
|||
extern HRESULT create_textlayout(const struct textlayout_desc*,IDWriteTextLayout**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_trimmingsign(IDWriteFactory4*,IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN;
|
||||
extern void gdiinterop_init(struct gdiinterop*,IDWriteFactory4*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN;
|
||||
|
@ -179,7 +172,7 @@ extern HRESULT get_eudc_fontcollection(IDWriteFactory4*,IDWriteFontCollection**)
|
|||
extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_fontface(const struct fontface_desc*,IDWriteFontFace4**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_fontface(const struct fontface_desc*,struct list*,IDWriteFontFace4**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_font_collection(IDWriteFactory4*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection1**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
|
||||
|
@ -198,9 +191,13 @@ extern HRESULT create_fontfacereference(IDWriteFactory4*,IDWriteFontFile*,UINT32
|
|||
IDWriteFontFaceReference**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT factory_get_cached_fontface(IDWriteFactory4*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace**,
|
||||
struct list**) DECLSPEC_HIDDEN;
|
||||
extern void factory_cache_fontface(struct list*,IDWriteFontFace4*) DECLSPEC_HIDDEN;
|
||||
extern void factory_detach_fontcollection(IDWriteFactory4*,IDWriteFontCollection1*) DECLSPEC_HIDDEN;
|
||||
extern void factory_detach_gdiinterop(IDWriteFactory4*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
|
||||
extern struct fontfacecached *factory_cache_fontface(struct list*,IDWriteFontFace4*) DECLSPEC_HIDDEN;
|
||||
extern void factory_release_cached_fontface(struct fontfacecached*) DECLSPEC_HIDDEN;
|
||||
extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*) DECLSPEC_HIDDEN;
|
||||
extern void get_logfont_from_fontface(IDWriteFontFace*,LOGFONTW*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_gdiinterop(IDWriteFactory4*,IDWriteGdiInterop1**) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Opentype font table functions */
|
||||
struct dwrite_font_props {
|
||||
|
|
|
@ -83,7 +83,6 @@ struct dwrite_font_data {
|
|||
IDWriteLocalizedStrings *names;
|
||||
|
||||
/* data needed to create fontface instance */
|
||||
IDWriteFactory4 *factory;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteFontFile *file;
|
||||
UINT32 face_index;
|
||||
|
@ -99,15 +98,6 @@ struct dwrite_font_data {
|
|||
BOOL oblique_sim_tested : 1;
|
||||
};
|
||||
|
||||
struct dwrite_fontlist {
|
||||
IDWriteFontList1 IDWriteFontList1_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFontFamily1 *family;
|
||||
struct dwrite_font_data **fonts;
|
||||
UINT32 font_count;
|
||||
};
|
||||
|
||||
struct dwrite_fontfamily_data {
|
||||
LONG ref;
|
||||
|
||||
|
@ -125,6 +115,7 @@ struct dwrite_fontcollection {
|
|||
IDWriteFontCollection1 IDWriteFontCollection1_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFactory4 *factory;
|
||||
struct dwrite_fontfamily_data **family_data;
|
||||
UINT32 family_count;
|
||||
UINT32 family_alloc;
|
||||
|
@ -135,18 +126,25 @@ struct dwrite_fontfamily {
|
|||
LONG ref;
|
||||
|
||||
struct dwrite_fontfamily_data *data;
|
||||
struct dwrite_fontcollection *collection;
|
||||
};
|
||||
|
||||
IDWriteFontCollection1 *collection;
|
||||
struct dwrite_fontlist {
|
||||
IDWriteFontList1 IDWriteFontList1_iface;
|
||||
LONG ref;
|
||||
|
||||
struct dwrite_font_data **fonts;
|
||||
UINT32 font_count;
|
||||
struct dwrite_fontfamily *family;
|
||||
};
|
||||
|
||||
struct dwrite_font {
|
||||
IDWriteFont3 IDWriteFont3_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFontFamily1 *family;
|
||||
|
||||
DWRITE_FONT_STYLE style;
|
||||
struct dwrite_font_data *data;
|
||||
struct dwrite_fontfamily *family;
|
||||
};
|
||||
|
||||
struct dwrite_fonttable {
|
||||
|
@ -223,6 +221,9 @@ struct dwrite_fontface {
|
|||
UINT32 file_count;
|
||||
UINT32 index;
|
||||
|
||||
IDWriteFactory4 *factory;
|
||||
struct fontfacecached *cached;
|
||||
|
||||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
|
@ -418,7 +419,6 @@ static void release_font_data(struct dwrite_font_data *data)
|
|||
IDWriteLocalizedStrings_Release(data->names);
|
||||
|
||||
IDWriteFontFile_Release(data->file);
|
||||
IDWriteFactory4_Release(data->factory);
|
||||
heap_free(data->facename);
|
||||
heap_free(data);
|
||||
}
|
||||
|
@ -500,6 +500,8 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
|
|||
heap_free(This->glyphs[i]);
|
||||
|
||||
freetype_notify_cacheremove(iface);
|
||||
factory_release_cached_fontface(This->cached);
|
||||
IDWriteFactory4_Release(This->factory);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
|
@ -1355,25 +1357,21 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace4
|
|||
|
||||
*fontface = NULL;
|
||||
|
||||
hr = factory_get_cached_fontface(data->factory, &data->file, data->face_index,
|
||||
font->data->simulations, (IDWriteFontFace**)fontface, &cached_list);
|
||||
if (hr != S_FALSE)
|
||||
hr = factory_get_cached_fontface(font->family->collection->factory, &data->file, data->face_index,
|
||||
font->data->simulations, (IDWriteFontFace **)fontface, &cached_list);
|
||||
if (hr == S_OK) {
|
||||
IDWriteFontFace4_AddRef(*fontface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
desc.factory = data->factory;
|
||||
desc.factory = font->family->collection->factory;
|
||||
desc.face_type = data->face_type;
|
||||
desc.files = &data->file;
|
||||
desc.files_number = 1;
|
||||
desc.index = data->face_index;
|
||||
desc.simulations = data->simulations;
|
||||
desc.font_data = data;
|
||||
hr = create_fontface(&desc, fontface);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
factory_cache_fontface(cached_list, *fontface);
|
||||
|
||||
return S_OK;
|
||||
return create_fontface(&desc, cached_list, fontface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefont_QueryInterface(IDWriteFont3 *iface, REFIID riid, void **obj)
|
||||
|
@ -1413,7 +1411,7 @@ static ULONG WINAPI dwritefont_Release(IDWriteFont3 *iface)
|
|||
TRACE("(%p)->(%d)\n", This, ref);
|
||||
|
||||
if (!ref) {
|
||||
IDWriteFontFamily1_Release(This->family);
|
||||
IDWriteFontFamily1_Release(&This->family->IDWriteFontFamily1_iface);
|
||||
release_font_data(This->data);
|
||||
heap_free(This);
|
||||
}
|
||||
|
@ -1457,6 +1455,7 @@ static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface)
|
|||
struct dwrite_font *This = impl_from_IDWriteFont3(iface);
|
||||
IDWriteFontFace4 *fontface;
|
||||
HRESULT hr;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
|
@ -1464,7 +1463,9 @@ static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface)
|
|||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
return IDWriteFontFace4_IsSymbolFont(fontface);
|
||||
ret = IDWriteFontFace4_IsSymbolFont(fontface);
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont3 *iface, IDWriteLocalizedStrings **names)
|
||||
|
@ -1507,10 +1508,11 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface,
|
|||
|
||||
if (table_exists) {
|
||||
hr = opentype_get_font_info_strings(table_data, stringid, &data->info_strings[stringid]);
|
||||
IDWriteFontFace4_ReleaseFontTable(fontface, context);
|
||||
if (FAILED(hr) || !data->info_strings[stringid])
|
||||
return hr;
|
||||
IDWriteFontFace4_ReleaseFontTable(fontface, context);
|
||||
}
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
}
|
||||
|
||||
hr = clone_localizedstring(data->info_strings[stringid], strings);
|
||||
|
@ -1555,6 +1557,7 @@ static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont3 *iface, UINT32 value,
|
|||
hr = IDWriteFontFace4_GetGlyphIndices(fontface, &value, 1, &index);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
|
||||
*exists = index != 0;
|
||||
return S_OK;
|
||||
|
@ -1593,7 +1596,9 @@ static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 m
|
|||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return IDWriteFontFace4_GetUnicodeRanges(fontface, max_count, ranges, count);
|
||||
hr = IDWriteFontFace4_GetUnicodeRanges(fontface, max_count, ranges, count);
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface)
|
||||
|
@ -1601,6 +1606,7 @@ static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface)
|
|||
struct dwrite_font *This = impl_from_IDWriteFont3(iface);
|
||||
IDWriteFontFace4 *fontface;
|
||||
HRESULT hr;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
|
@ -1608,7 +1614,9 @@ static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface)
|
|||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
return IDWriteFontFace4_IsMonospacedFont(fontface);
|
||||
ret = IDWriteFontFace4_IsMonospacedFont(fontface);
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface)
|
||||
|
@ -1616,6 +1624,7 @@ static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface)
|
|||
struct dwrite_font *This = impl_from_IDWriteFont3(iface);
|
||||
IDWriteFontFace4 *fontface;
|
||||
HRESULT hr;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
|
@ -1623,21 +1632,18 @@ static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface)
|
|||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
return IDWriteFontFace4_IsColorFont(fontface);
|
||||
ret = IDWriteFontFace4_IsColorFont(fontface);
|
||||
IDWriteFontFace4_Release(fontface);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefont3_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace3 **fontface)
|
||||
{
|
||||
struct dwrite_font *This = impl_from_IDWriteFont3(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, fontface);
|
||||
|
||||
hr = get_fontface_from_font(This, (IDWriteFontFace4**)fontface);
|
||||
if (hr == S_OK)
|
||||
IDWriteFontFace3_AddRef(*fontface);
|
||||
|
||||
return hr;
|
||||
return get_fontface_from_font(This, (IDWriteFontFace4 **)fontface);
|
||||
}
|
||||
|
||||
static BOOL WINAPI dwritefont3_Equals(IDWriteFont3 *iface, IDWriteFont *font)
|
||||
|
@ -1653,8 +1659,8 @@ static HRESULT WINAPI dwritefont3_GetFontFaceReference(IDWriteFont3 *iface, IDWr
|
|||
|
||||
TRACE("(%p)->(%p)\n", This, reference);
|
||||
|
||||
return IDWriteFactory4_CreateFontFaceReference_(This->data->factory, This->data->file, This->data->face_index,
|
||||
This->data->simulations, reference);
|
||||
return IDWriteFactory4_CreateFontFaceReference_(This->family->collection->factory, This->data->file,
|
||||
This->data->face_index, This->data->simulations, reference);
|
||||
}
|
||||
|
||||
static BOOL WINAPI dwritefont3_HasCharacter(IDWriteFont3 *iface, UINT32 ch)
|
||||
|
@ -1731,18 +1737,20 @@ void get_logfont_from_fontface(IDWriteFontFace *iface, LOGFONTW *lf)
|
|||
*lf = fontface->lf;
|
||||
}
|
||||
|
||||
static HRESULT create_font(struct dwrite_font_data *data, IDWriteFontFamily1 *family, IDWriteFont3 **font)
|
||||
static HRESULT create_font(struct dwrite_font_data *data, struct dwrite_fontfamily *family, IDWriteFont3 **font)
|
||||
{
|
||||
struct dwrite_font *This;
|
||||
|
||||
*font = NULL;
|
||||
|
||||
This = heap_alloc(sizeof(struct dwrite_font));
|
||||
if (!This) return E_OUTOFMEMORY;
|
||||
This = heap_alloc(sizeof(*This));
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->IDWriteFont3_iface.lpVtbl = &dwritefontvtbl;
|
||||
This->ref = 1;
|
||||
This->family = family;
|
||||
IDWriteFontFamily1_AddRef(family);
|
||||
IDWriteFontFamily1_AddRef(&family->IDWriteFontFamily1_iface);
|
||||
This->style = data->style;
|
||||
This->data = data;
|
||||
InterlockedIncrement(&This->data->ref);
|
||||
|
@ -1792,7 +1800,7 @@ static ULONG WINAPI dwritefontlist_Release(IDWriteFontList1 *iface)
|
|||
|
||||
for (i = 0; i < This->font_count; i++)
|
||||
release_font_data(This->fonts[i]);
|
||||
IDWriteFontFamily1_Release(This->family);
|
||||
IDWriteFontFamily1_Release(&This->family->IDWriteFontFamily1_iface);
|
||||
heap_free(This->fonts);
|
||||
heap_free(This);
|
||||
}
|
||||
|
@ -1803,7 +1811,7 @@ static ULONG WINAPI dwritefontlist_Release(IDWriteFontList1 *iface)
|
|||
static HRESULT WINAPI dwritefontlist_GetFontCollection(IDWriteFontList1 *iface, IDWriteFontCollection **collection)
|
||||
{
|
||||
struct dwrite_fontlist *This = impl_from_IDWriteFontList1(iface);
|
||||
return IDWriteFontFamily1_GetFontCollection(This->family, collection);
|
||||
return IDWriteFontFamily1_GetFontCollection(&This->family->IDWriteFontFamily1_iface, collection);
|
||||
}
|
||||
|
||||
static UINT32 WINAPI dwritefontlist_GetFontCount(IDWriteFontList1 *iface)
|
||||
|
@ -1827,7 +1835,7 @@ static HRESULT WINAPI dwritefontlist_GetFont(IDWriteFontList1 *iface, UINT32 ind
|
|||
if (index >= This->font_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return create_font(This->fonts[index], This->family, (IDWriteFont3**)font);
|
||||
return create_font(This->fonts[index], This->family, (IDWriteFont3 **)font);
|
||||
}
|
||||
|
||||
static DWRITE_LOCALITY WINAPI dwritefontlist1_GetFontLocality(IDWriteFontList1 *iface, UINT32 index)
|
||||
|
@ -1926,7 +1934,7 @@ static ULONG WINAPI dwritefontfamily_Release(IDWriteFontFamily1 *iface)
|
|||
|
||||
if (!ref)
|
||||
{
|
||||
IDWriteFontCollection1_Release(This->collection);
|
||||
IDWriteFontCollection1_Release(&This->collection->IDWriteFontCollection1_iface);
|
||||
release_fontfamily_data(This->data);
|
||||
heap_free(This);
|
||||
}
|
||||
|
@ -1966,7 +1974,7 @@ static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily1 *iface, UINT32
|
|||
if (index >= This->data->font_count)
|
||||
return E_INVALIDARG;
|
||||
|
||||
return create_font(This->data->fonts[index], iface, (IDWriteFont3**)font);
|
||||
return create_font(This->data->fonts[index], This, (IDWriteFont3 **)font);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily1 *iface, IDWriteLocalizedStrings **names)
|
||||
|
@ -2039,7 +2047,7 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily1 *
|
|||
match = This->data->fonts[i];
|
||||
}
|
||||
|
||||
return create_font(match, iface, (IDWriteFont3**)font);
|
||||
return create_font(match, This, (IDWriteFont3 **)font);
|
||||
}
|
||||
|
||||
typedef BOOL (*matching_filter_func)(const struct dwrite_font_data*);
|
||||
|
@ -2102,8 +2110,8 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *ifac
|
|||
|
||||
fonts->IDWriteFontList1_iface.lpVtbl = &dwritefontlistvtbl;
|
||||
fonts->ref = 1;
|
||||
fonts->family = iface;
|
||||
IDWriteFontFamily1_AddRef(fonts->family);
|
||||
fonts->family = This;
|
||||
IDWriteFontFamily1_AddRef(&fonts->family->IDWriteFontFamily1_iface);
|
||||
fonts->font_count = 0;
|
||||
|
||||
/* Normal style accepts Normal or Italic, Oblique and Italic - both Oblique and Italic styles */
|
||||
|
@ -2155,7 +2163,7 @@ static HRESULT WINAPI dwritefontfamily1_GetFont(IDWriteFontFamily1 *iface, UINT3
|
|||
if (index >= This->data->font_count)
|
||||
return E_FAIL;
|
||||
|
||||
return create_font(This->data->fonts[index], iface, font);
|
||||
return create_font(This->data->fonts[index], This, font);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontfamily1_GetFontFaceReference(IDWriteFontFamily1 *iface, UINT32 index,
|
||||
|
@ -2194,7 +2202,8 @@ static const IDWriteFontFamily1Vtbl fontfamilyvtbl = {
|
|||
dwritefontfamily1_GetFontFaceReference
|
||||
};
|
||||
|
||||
static HRESULT create_fontfamily(struct dwrite_fontfamily_data *data, IDWriteFontCollection1 *collection, IDWriteFontFamily1 **family)
|
||||
static HRESULT create_fontfamily(struct dwrite_fontfamily_data *data, struct dwrite_fontcollection *collection,
|
||||
IDWriteFontFamily1 **family)
|
||||
{
|
||||
struct dwrite_fontfamily *This;
|
||||
|
||||
|
@ -2206,7 +2215,7 @@ static HRESULT create_fontfamily(struct dwrite_fontfamily_data *data, IDWriteFon
|
|||
This->IDWriteFontFamily1_iface.lpVtbl = &fontfamilyvtbl;
|
||||
This->ref = 1;
|
||||
This->collection = collection;
|
||||
IDWriteFontCollection1_AddRef(collection);
|
||||
IDWriteFontCollection1_AddRef(&collection->IDWriteFontCollection1_iface);
|
||||
This->data = data;
|
||||
InterlockedIncrement(&This->data->ref);
|
||||
|
||||
|
@ -2272,12 +2281,15 @@ static ULONG WINAPI dwritefontcollection_AddRef(IDWriteFontCollection1 *iface)
|
|||
|
||||
static ULONG WINAPI dwritefontcollection_Release(IDWriteFontCollection1 *iface)
|
||||
{
|
||||
unsigned int i;
|
||||
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection1(iface);
|
||||
ULONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(%d)\n", This, ref);
|
||||
|
||||
if (!ref) {
|
||||
int i;
|
||||
|
||||
factory_detach_fontcollection(This->factory, iface);
|
||||
for (i = 0; i < This->family_count; i++)
|
||||
release_fontfamily_data(This->family_data[i]);
|
||||
heap_free(This->family_data);
|
||||
|
@ -2305,7 +2317,7 @@ static HRESULT WINAPI dwritefontcollection_GetFontFamily(IDWriteFontCollection1
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return create_fontfamily(This->family_data[index], iface, (IDWriteFontFamily1**)family);
|
||||
return create_fontfamily(This->family_data[index], This, (IDWriteFontFamily1 **)family);
|
||||
}
|
||||
|
||||
static UINT32 collection_find_family(struct dwrite_fontcollection *collection, const WCHAR *name)
|
||||
|
@ -2399,11 +2411,11 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
|
|||
if (!found_font)
|
||||
return DWRITE_E_NOFONT;
|
||||
|
||||
hr = create_fontfamily(found_family, iface, &family);
|
||||
hr = create_fontfamily(found_family, This, &family);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
hr = create_font(found_font, family, (IDWriteFont3**)font);
|
||||
hr = create_font(found_font, impl_from_IDWriteFontFamily1(family), (IDWriteFont3 **)font);
|
||||
IDWriteFontFamily1_Release(family);
|
||||
return hr;
|
||||
}
|
||||
|
@ -2428,7 +2440,7 @@ static HRESULT WINAPI dwritefontcollection1_GetFontFamily(IDWriteFontCollection1
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
return create_fontfamily(This->family_data[index], iface, family);
|
||||
return create_fontfamily(This->family_data[index], This, family);
|
||||
}
|
||||
|
||||
static const IDWriteFontCollection1Vtbl fontcollectionvtbl = {
|
||||
|
@ -2495,9 +2507,7 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio
|
|||
collection->family_data = new_list;
|
||||
}
|
||||
|
||||
collection->family_data[collection->family_count] = family;
|
||||
collection->family_count++;
|
||||
|
||||
collection->family_data[collection->family_count++] = family;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3272,7 +3282,6 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
|
|||
}
|
||||
|
||||
data->ref = 1;
|
||||
data->factory = desc->factory;
|
||||
data->file = desc->files[0];
|
||||
data->face_index = desc->index;
|
||||
data->face_type = desc->face_type;
|
||||
|
@ -3280,7 +3289,6 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
|
|||
data->bold_sim_tested = 0;
|
||||
data->oblique_sim_tested = 0;
|
||||
IDWriteFontFile_AddRef(data->file);
|
||||
IDWriteFactory4_AddRef(data->factory);
|
||||
|
||||
stream_desc.stream = stream;
|
||||
stream_desc.face_type = desc->face_type;
|
||||
|
@ -3317,12 +3325,13 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRITE_FONT_SIMULATIONS sim, const WCHAR *facenameW,
|
||||
struct dwrite_font_data **ret)
|
||||
static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRITE_FONT_SIMULATIONS sim,
|
||||
const WCHAR *facenameW, struct dwrite_font_data **ret)
|
||||
{
|
||||
struct dwrite_font_data *data;
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
data = heap_alloc_zero(sizeof(*data));
|
||||
if (!data)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -3336,7 +3345,6 @@ static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRI
|
|||
data->style = DWRITE_FONT_STYLE_OBLIQUE;
|
||||
memset(data->info_strings, 0, sizeof(data->info_strings));
|
||||
data->names = NULL;
|
||||
IDWriteFactory4_AddRef(data->factory);
|
||||
IDWriteFontFile_AddRef(data->file);
|
||||
|
||||
create_localizedstrings(&data->names);
|
||||
|
@ -3738,6 +3746,9 @@ HRESULT create_font_collection(IDWriteFactory4 *factory, IDWriteFontFileEnumerat
|
|||
if (is_system)
|
||||
fontcollection_add_replacements(collection);
|
||||
|
||||
collection->factory = factory;
|
||||
IDWriteFactory4_AddRef(factory);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -3749,6 +3760,9 @@ struct system_fontfile_enumerator
|
|||
IDWriteFactory4 *factory;
|
||||
HKEY hkey;
|
||||
int index;
|
||||
|
||||
WCHAR *value;
|
||||
DWORD max_val_count;
|
||||
};
|
||||
|
||||
static inline struct system_fontfile_enumerator *impl_from_IDWriteFontFileEnumerator(IDWriteFontFileEnumerator* iface)
|
||||
|
@ -3783,6 +3797,7 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *
|
|||
if (!ref) {
|
||||
IDWriteFactory4_Release(enumerator->factory);
|
||||
RegCloseKey(enumerator->hkey);
|
||||
heap_free(enumerator->value);
|
||||
heap_free(enumerator);
|
||||
}
|
||||
|
||||
|
@ -3852,29 +3867,30 @@ static HRESULT WINAPI systemfontfileenumerator_GetCurrentFontFile(IDWriteFontFil
|
|||
static HRESULT WINAPI systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerator *iface, BOOL *current)
|
||||
{
|
||||
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
|
||||
DWORD ret, max_val_count;
|
||||
WCHAR *value;
|
||||
|
||||
*current = FALSE;
|
||||
enumerator->index++;
|
||||
|
||||
ret = RegQueryInfoKeyW(enumerator->hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &max_val_count, NULL, NULL, NULL);
|
||||
if (ret != ERROR_SUCCESS)
|
||||
return E_FAIL;
|
||||
if (!enumerator->value) {
|
||||
if (RegQueryInfoKeyW(enumerator->hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&enumerator->max_val_count, NULL, NULL, NULL))
|
||||
return E_FAIL;
|
||||
|
||||
max_val_count++;
|
||||
if (!(value = heap_alloc( max_val_count * sizeof(value[0]) )))
|
||||
return E_OUTOFMEMORY;
|
||||
enumerator->max_val_count++;
|
||||
if (!(enumerator->value = heap_alloc(enumerator->max_val_count * sizeof(*enumerator->value))))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* iterate until we find next string value */
|
||||
while (1) {
|
||||
for (;;) {
|
||||
DWORD type = 0, count, val_count;
|
||||
|
||||
val_count = max_val_count;
|
||||
value[0] = 0;
|
||||
if (RegEnumValueW(enumerator->hkey, enumerator->index, value, &val_count, NULL, &type, NULL, &count))
|
||||
val_count = enumerator->max_val_count;
|
||||
*enumerator->value = 0;
|
||||
if (RegEnumValueW(enumerator->hkey, enumerator->index, enumerator->value, &val_count,
|
||||
NULL, &type, NULL, &count))
|
||||
break;
|
||||
if (type == REG_SZ && *value && *value != '@') {
|
||||
if (type == REG_SZ && *enumerator->value && *enumerator->value != '@') {
|
||||
*current = TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -3882,7 +3898,6 @@ static HRESULT WINAPI systemfontfileenumerator_MoveNext(IDWriteFontFileEnumerato
|
|||
}
|
||||
|
||||
TRACE("index = %d, current = %d\n", enumerator->index, *current);
|
||||
heap_free(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3914,6 +3929,8 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory4 *factory, IDWri
|
|||
enumerator->ref = 1;
|
||||
enumerator->factory = factory;
|
||||
enumerator->index = -1;
|
||||
enumerator->value = NULL;
|
||||
enumerator->max_val_count = 0;
|
||||
IDWriteFactory4_AddRef(factory);
|
||||
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, fontslistW, 0, GENERIC_READ, &enumerator->hkey)) {
|
||||
|
@ -4238,7 +4255,7 @@ static HRESULT get_stream_from_file(IDWriteFontFile *file, IDWriteFontFileStream
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace4 **ret)
|
||||
HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace4 **ret)
|
||||
{
|
||||
struct file_stream_desc stream_desc;
|
||||
struct dwrite_fontface *fontface;
|
||||
|
@ -4346,6 +4363,9 @@ HRESULT create_fontface(const struct fontface_desc *desc, IDWriteFontFace4 **ret
|
|||
release_font_data(data);
|
||||
}
|
||||
|
||||
fontface->cached = factory_cache_fontface(cached_list, &fontface->IDWriteFontFace4_iface);
|
||||
IDWriteFactory4_AddRef(fontface->factory = desc->factory);
|
||||
|
||||
*ret = &fontface->IDWriteFontFace4_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -5627,7 +5647,7 @@ static HRESULT WINAPI fontfacereference_CreateFontFaceWithSimulations(IDWriteFon
|
|||
|
||||
hr = IDWriteFactory4_CreateFontFace(This->factory, face_type, 1, &This->file, This->index, simulations, &fontface);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace4, (void**)ret);
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void **)ret);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,12 @@ struct rendertarget {
|
|||
struct dib_data dib;
|
||||
};
|
||||
|
||||
struct gdiinterop {
|
||||
IDWriteGdiInterop1 IDWriteGdiInterop1_iface;
|
||||
LONG ref;
|
||||
IDWriteFactory4 *factory;
|
||||
};
|
||||
|
||||
static inline int get_dib_stride(int width, int bpp)
|
||||
{
|
||||
return ((width * bpp + 31) >> 3) & ~3;
|
||||
|
@ -598,15 +604,24 @@ static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop1 *iface, REFII
|
|||
static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop1 *iface)
|
||||
{
|
||||
struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IDWriteFactory4_AddRef(This->factory);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
TRACE("(%p)->(%d)\n", This, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop1 *iface)
|
||||
{
|
||||
struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
|
||||
TRACE("(%p)\n", This);
|
||||
return IDWriteFactory4_Release(This->factory);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p)->(%d)\n", This, ref);
|
||||
|
||||
if (!ref) {
|
||||
factory_detach_gdiinterop(This->factory, iface);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop1 *iface,
|
||||
|
@ -890,10 +905,19 @@ static const struct IDWriteGdiInterop1Vtbl gdiinteropvtbl = {
|
|||
gdiinterop1_GetMatchingFontsByLOGFONT
|
||||
};
|
||||
|
||||
void gdiinterop_init(struct gdiinterop *interop, IDWriteFactory4 *factory)
|
||||
HRESULT create_gdiinterop(IDWriteFactory4 *factory, IDWriteGdiInterop1 **ret)
|
||||
{
|
||||
struct gdiinterop *interop;
|
||||
|
||||
*ret = NULL;
|
||||
|
||||
if (!(interop = heap_alloc(sizeof(*interop))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
interop->IDWriteGdiInterop1_iface.lpVtbl = &gdiinteropvtbl;
|
||||
/* Interop is a part of a factory, sharing its refcount.
|
||||
GetGdiInterop() will AddRef() on every call. */
|
||||
interop->factory = factory;
|
||||
interop->ref = 1;
|
||||
IDWriteFactory4_AddRef(interop->factory = factory);
|
||||
|
||||
*ret = &interop->IDWriteGdiInterop1_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -538,7 +538,7 @@ struct dwritefactory {
|
|||
|
||||
IDWriteFontCollection1 *system_collection;
|
||||
IDWriteFontCollection *eudc_collection;
|
||||
struct gdiinterop interop;
|
||||
IDWriteGdiInterop1 *gdiinterop;
|
||||
IDWriteFontFallback *fallback;
|
||||
|
||||
IDWriteLocalFontFileLoader* localfontfileloader;
|
||||
|
@ -556,9 +556,9 @@ static inline struct dwritefactory *impl_from_IDWriteFactory4(IDWriteFactory4 *i
|
|||
static void release_fontface_cache(struct list *fontfaces)
|
||||
{
|
||||
struct fontfacecached *fontface, *fontface2;
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(fontface, fontface2, fontfaces, struct fontfacecached, entry) {
|
||||
list_remove(&fontface->entry);
|
||||
IDWriteFontFace4_Release(fontface->fontface);
|
||||
heap_free(fontface);
|
||||
}
|
||||
}
|
||||
|
@ -875,36 +875,44 @@ HRESULT factory_get_cached_fontface(IDWriteFactory4 *iface, IDWriteFontFile * co
|
|||
return S_FALSE;
|
||||
}
|
||||
|
||||
void factory_cache_fontface(struct list *fontfaces, IDWriteFontFace4 *fontface)
|
||||
struct fontfacecached *factory_cache_fontface(struct list *fontfaces, IDWriteFontFace4 *fontface)
|
||||
{
|
||||
struct fontfacecached *cached;
|
||||
|
||||
/* new cache entry */
|
||||
cached = heap_alloc(sizeof(*cached));
|
||||
if (!cached)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
cached->fontface = fontface;
|
||||
list_add_tail(fontfaces, &cached->entry);
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface,
|
||||
DWRITE_FONT_FACE_TYPE req_facetype, UINT32 files_number, IDWriteFontFile* const* font_files,
|
||||
UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFace **font_face)
|
||||
void factory_release_cached_fontface(struct fontfacecached *cached)
|
||||
{
|
||||
list_remove(&cached->entry);
|
||||
heap_free(cached);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface, DWRITE_FONT_FACE_TYPE req_facetype,
|
||||
UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS simulations,
|
||||
IDWriteFontFace **fontface)
|
||||
{
|
||||
struct dwritefactory *This = impl_from_IDWriteFactory4(iface);
|
||||
DWRITE_FONT_FILE_TYPE file_type;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
struct fontface_desc desc;
|
||||
struct list *fontfaces;
|
||||
IDWriteFontFace4 *face;
|
||||
BOOL is_supported;
|
||||
UINT32 count;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index, simulations, font_face);
|
||||
TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index,
|
||||
simulations, fontface);
|
||||
|
||||
*font_face = NULL;
|
||||
*fontface = NULL;
|
||||
|
||||
if (!is_face_type_supported(req_facetype))
|
||||
return E_INVALIDARG;
|
||||
|
@ -928,9 +936,9 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface,
|
|||
if (face_type != req_facetype)
|
||||
return DWRITE_E_FILEFORMAT;
|
||||
|
||||
hr = factory_get_cached_fontface(iface, font_files, index, simulations, font_face, &fontfaces);
|
||||
hr = factory_get_cached_fontface(iface, font_files, index, simulations, fontface, &fontfaces);
|
||||
if (hr == S_OK)
|
||||
IDWriteFontFace_AddRef(*font_face);
|
||||
IDWriteFontFace_AddRef(*fontface);
|
||||
|
||||
if (hr != S_FALSE)
|
||||
return hr;
|
||||
|
@ -942,16 +950,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory4 *iface,
|
|||
desc.index = index;
|
||||
desc.simulations = simulations;
|
||||
desc.font_data = NULL;
|
||||
hr = create_fontface(&desc, &face);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
factory_cache_fontface(fontfaces, face);
|
||||
|
||||
*font_face = (IDWriteFontFace*)face;
|
||||
IDWriteFontFace_AddRef(*font_face);
|
||||
|
||||
return S_OK;
|
||||
return create_fontface(&desc, fontfaces, (IDWriteFontFace4 **)fontface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory4 *iface, IDWriteRenderingParams **params)
|
||||
|
@ -1083,12 +1082,18 @@ static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory4 *iface, IDW
|
|||
static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory4 *iface, IDWriteGdiInterop **gdi_interop)
|
||||
{
|
||||
struct dwritefactory *This = impl_from_IDWriteFactory4(iface);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, gdi_interop);
|
||||
|
||||
*gdi_interop = (IDWriteGdiInterop*)&This->interop.IDWriteGdiInterop1_iface;
|
||||
IDWriteGdiInterop_AddRef(*gdi_interop);
|
||||
return S_OK;
|
||||
if (This->gdiinterop)
|
||||
IDWriteGdiInterop1_AddRef(This->gdiinterop);
|
||||
else
|
||||
hr = create_gdiinterop(iface, &This->gdiinterop);
|
||||
|
||||
*gdi_interop = (IDWriteGdiInterop *)This->gdiinterop;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory4 *iface, WCHAR const* string,
|
||||
|
@ -1407,11 +1412,10 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory4 *if
|
|||
if (check_for_updates)
|
||||
FIXME("checking for system font updates not implemented\n");
|
||||
|
||||
if (!This->system_collection)
|
||||
hr = get_system_fontcollection(iface, &This->system_collection);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
if (This->system_collection)
|
||||
IDWriteFontCollection1_AddRef(This->system_collection);
|
||||
else
|
||||
hr = get_system_fontcollection(iface, &This->system_collection);
|
||||
|
||||
*collection = This->system_collection;
|
||||
|
||||
|
@ -1646,7 +1650,7 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP
|
|||
factory->localfontfileloader = NULL;
|
||||
factory->system_collection = NULL;
|
||||
factory->eudc_collection = NULL;
|
||||
gdiinterop_init(&factory->interop, &factory->IDWriteFactory4_iface);
|
||||
factory->gdiinterop = NULL;
|
||||
factory->fallback = NULL;
|
||||
|
||||
list_init(&factory->collection_loaders);
|
||||
|
@ -1654,6 +1658,21 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP
|
|||
list_init(&factory->localfontfaces);
|
||||
}
|
||||
|
||||
void factory_detach_fontcollection(IDWriteFactory4 *iface, IDWriteFontCollection1 *collection)
|
||||
{
|
||||
struct dwritefactory *factory = impl_from_IDWriteFactory4(iface);
|
||||
if (factory->system_collection == collection)
|
||||
factory->system_collection = NULL;
|
||||
IDWriteFactory4_Release(iface);
|
||||
}
|
||||
|
||||
void factory_detach_gdiinterop(IDWriteFactory4 *iface, IDWriteGdiInterop1 *interop)
|
||||
{
|
||||
struct dwritefactory *factory = impl_from_IDWriteFactory4(iface);
|
||||
factory->gdiinterop = NULL;
|
||||
IDWriteFactory4_Release(iface);
|
||||
}
|
||||
|
||||
HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
|
||||
{
|
||||
struct dwritefactory *factory;
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue