Nikolay Sivov : dwrite: Make font set entries refcounted.
Alexandre Julliard
julliard at winehq.org
Wed Mar 10 14:58:45 CST 2021
Module: wine
Branch: master
Commit: dc37782f663497413f27309e10cf7a1584bac33c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=dc37782f663497413f27309e10cf7a1584bac33c
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Mar 10 12:30:27 2021 +0300
dwrite: Make font set entries refcounted.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dwrite/font.c | 105 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 64 insertions(+), 41 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 1afc72e22c5..07d96dfe107 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -252,6 +252,7 @@ struct dwrite_fontresource
struct dwrite_fontset_entry
{
+ LONG refcount;
IDWriteFontFile *file;
unsigned int face_index;
unsigned int simulations;
@@ -263,7 +264,7 @@ struct dwrite_fontset
LONG refcount;
IDWriteFactory7 *factory;
- struct dwrite_fontset_entry *entries;
+ struct dwrite_fontset_entry **entries;
unsigned int count;
};
@@ -273,7 +274,7 @@ struct dwrite_fontset_builder
LONG refcount;
IDWriteFactory7 *factory;
- struct dwrite_fontset_entry *entries;
+ struct dwrite_fontset_entry **entries;
size_t count;
size_t capacity;
};
@@ -7103,25 +7104,27 @@ static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface)
return refcount;
}
-static void fontset_release_entries(struct dwrite_fontset_entry *entries, unsigned int count)
+static void release_fontset_entry(struct dwrite_fontset_entry *entry)
{
- unsigned int i;
-
- for (i = 0; i < count; ++i)
- IDWriteFontFile_Release(entries[i].file);
+ if (InterlockedDecrement(&entry->refcount) > 0)
+ return;
+ IDWriteFontFile_Release(entry->file);
+ heap_free(entry);
}
static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface)
{
struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface);
ULONG refcount = InterlockedDecrement(&set->refcount);
+ unsigned int i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount)
{
IDWriteFactory7_Release(set->factory);
- fontset_release_entries(set->entries, set->count);
+ for (i = 0; i < set->count; ++i)
+ release_fontset_entry(set->entries[i]);
heap_free(set->entries);
heap_free(set);
}
@@ -7142,7 +7145,6 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface,
IDWriteFontFaceReference **reference)
{
struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface);
- struct dwrite_fontset_entry *entry;
TRACE("%p, %u, %p.\n", iface, index, reference);
@@ -7151,9 +7153,8 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface,
if (index >= set->count)
return E_INVALIDARG;
- entry = &set->entries[index];
- return IDWriteFactory7_CreateFontFaceReference_(set->factory, entry->file, entry->face_index,
- entry->simulations, reference);
+ return IDWriteFactory7_CreateFontFaceReference_(set->factory, set->entries[index]->file,
+ set->entries[index]->face_index, set->entries[index]->simulations, reference);
}
static HRESULT WINAPI dwritefontset_FindFontFaceReference(IDWriteFontSet3 *iface,
@@ -7386,65 +7387,85 @@ static const IDWriteFontSet3Vtbl fontsetvtbl =
dwritefontset3_GetFontSourceName,
};
-static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts,
- unsigned int count, IDWriteFontSet1 **ret)
+static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_index,
+ unsigned int simulations, struct dwrite_fontset_entry **ret)
{
- struct dwrite_fontset *object;
- unsigned int i;
+ struct dwrite_fontset_entry *entry;
- if (!(object = heap_alloc_zero(sizeof(*object))))
+ if (!(entry = heap_alloc_zero(sizeof(*entry))))
return E_OUTOFMEMORY;
+ entry->refcount = 1;
+ entry->file = file;
+ IDWriteFontFile_AddRef(entry->file);
+ entry->face_index = face_index;
+ entry->simulations = simulations;
+
+ *ret = entry;
+
+ return S_OK;
+}
+
+static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory,
+ struct dwrite_fontset_entry **entries, unsigned int count)
+{
object->IDWriteFontSet3_iface.lpVtbl = &fontsetvtbl;
object->refcount = 1;
object->factory = factory;
IDWriteFactory7_AddRef(object->factory);
+ object->entries = entries;
+ object->count = count;
+}
+
+static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dwrite_font_data **fonts,
+ unsigned int count, IDWriteFontSet1 **ret)
+{
+ struct dwrite_fontset_entry **entries = NULL;
+ struct dwrite_fontset *object;
+ unsigned int i;
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
if (count)
{
- object->entries = heap_calloc(count, sizeof(*object->entries));
- object->count = count;
+ entries = heap_calloc(count, sizeof(*entries));
/* FIXME: set available properties too */
- for (i = 0; i < object->count; ++i)
+
+ for (i = 0; i < count; ++i)
{
- object->entries[i].file = fonts[i]->file;
- object->entries[i].face_index = fonts[i]->face_index;
- object->entries[i].simulations = fonts[i]->simulations;
- IDWriteFontFile_AddRef(object->entries[i].file);
+ fontset_create_entry(fonts[i]->file, fonts[i]->face_index, fonts[i]->simulations, &entries[i]);
}
}
+ init_fontset(object, factory, entries, count);
*ret = (IDWriteFontSet1 *)&object->IDWriteFontSet3_iface;
return S_OK;
}
-static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry *entries,
+static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct dwrite_fontset_entry **src_entries,
unsigned int count, IDWriteFontSet **ret)
{
+ struct dwrite_fontset_entry **entries = NULL;
struct dwrite_fontset *object;
unsigned int i;
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- object->IDWriteFontSet3_iface.lpVtbl = &fontsetvtbl;
- object->refcount = 1;
- object->factory = factory;
- IDWriteFactory7_AddRef(object->factory);
-
if (count)
{
- object->entries = heap_calloc(count, sizeof(*object->entries));
- object->count = count;
+ entries = heap_calloc(count, sizeof(*entries));
- for (i = 0; i < object->count; ++i)
+ for (i = 0; i < count; ++i)
{
- object->entries[i] = entries[i];
- IDWriteFontFile_AddRef(object->entries[i].file);
+ entries[i] = src_entries[i];
+ InterlockedIncrement(&entries[i]->refcount);
}
}
+ init_fontset(object, factory, entries, count);
*ret = (IDWriteFontSet *)&object->IDWriteFontSet3_iface;
@@ -7485,13 +7506,15 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface)
{
struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface);
ULONG refcount = InterlockedDecrement(&builder->refcount);
+ unsigned int i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount)
{
IDWriteFactory7_Release(builder->factory);
- fontset_release_entries(builder->entries, builder->count);
+ for (i = 0; i < builder->count; ++i)
+ release_fontset_entry(builder->entries[i]);
heap_free(builder->entries);
heap_free(builder);
}
@@ -7503,6 +7526,7 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder,
unsigned int face_index, unsigned int simulations)
{
struct dwrite_fontset_entry *entry;
+ HRESULT hr;
if (!dwrite_array_reserve((void **)&builder->entries, &builder->capacity, builder->count + 1,
sizeof(*builder->entries)))
@@ -7510,11 +7534,10 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder,
return E_OUTOFMEMORY;
}
- entry = &builder->entries[builder->count++];
- entry->file = file;
- IDWriteFontFile_AddRef(entry->file);
- entry->face_index = face_index;
- entry->simulations = simulations;
+ if (FAILED(hr = fontset_create_entry(file, face_index, simulations, &entry)))
+ return hr;
+
+ builder->entries[builder->count++] = entry;
return S_OK;
}
More information about the wine-cvs
mailing list