dwrite: Use array allocation helper to manage family entries.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-05-14 13:27:23 +03:00 committed by Alexandre Julliard
parent 8958eb68d7
commit 958911c699
1 changed files with 82 additions and 84 deletions

View File

@ -99,14 +99,16 @@ struct dwrite_font_data {
BOOL oblique_sim_tested : 1; BOOL oblique_sim_tested : 1;
}; };
struct dwrite_fontfamily_data { struct dwrite_fontfamily_data
LONG ref; {
LONG refcount;
IDWriteLocalizedStrings *familyname; IDWriteLocalizedStrings *familyname;
struct dwrite_font_data **fonts; struct dwrite_font_data **fonts;
UINT32 font_count; size_t size;
UINT32 font_alloc; size_t count;
BOOL has_normal_face : 1; BOOL has_normal_face : 1;
BOOL has_oblique_face : 1; BOOL has_oblique_face : 1;
BOOL has_italic_face : 1; BOOL has_italic_face : 1;
@ -428,12 +430,12 @@ static void release_font_data(struct dwrite_font_data *data)
static void release_fontfamily_data(struct dwrite_fontfamily_data *data) static void release_fontfamily_data(struct dwrite_fontfamily_data *data)
{ {
int i; size_t i;
if (InterlockedDecrement(&data->ref) > 0) if (InterlockedDecrement(&data->refcount) > 0)
return; return;
for (i = 0; i < data->font_count; i++) for (i = 0; i < data->count; ++i)
release_font_data(data->fonts[i]); release_font_data(data->fonts[i]);
heap_free(data->fonts); heap_free(data->fonts);
IDWriteLocalizedStrings_Release(data->familyname); IDWriteLocalizedStrings_Release(data->familyname);
@ -2043,26 +2045,28 @@ static HRESULT WINAPI dwritefontfamily_GetFontCollection(IDWriteFontFamily1 *ifa
static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily1 *iface) static UINT32 WINAPI dwritefontfamily_GetFontCount(IDWriteFontFamily1 *iface)
{ {
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily1(iface); struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily1(iface);
TRACE("(%p)\n", This);
return This->data->font_count; TRACE("%p.\n", iface);
return family->data->count;
} }
static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily1 *iface, UINT32 index, IDWriteFont **font) static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily1 *iface, UINT32 index, IDWriteFont **font)
{ {
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily1(iface); struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily1(iface);
TRACE("(%p)->(%u %p)\n", This, index, font); TRACE("%p, %u, %p.\n", iface, index, font);
*font = NULL; *font = NULL;
if (This->data->font_count == 0) if (!family->data->count)
return S_FALSE; return S_FALSE;
if (index >= This->data->font_count) if (index >= family->data->count)
return E_INVALIDARG; return E_INVALIDARG;
return create_font(This, index, (IDWriteFont3 **)font); return create_font(family, index, (IDWriteFont3 **)font);
} }
static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily1 *iface, IDWriteLocalizedStrings **names) static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily1 *iface, IDWriteLocalizedStrings **names)
@ -2115,13 +2119,14 @@ static BOOL is_better_font_match(const struct dwrite_font_propvec *next, const s
static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily1 *iface, DWRITE_FONT_WEIGHT weight, static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily1 *iface, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont **font) DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont **font)
{ {
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily1(iface); struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily1(iface);
struct dwrite_font_propvec req; struct dwrite_font_propvec req;
UINT32 i, match; size_t i, match;
TRACE("(%p)->(%d %d %d %p)\n", This, weight, stretch, style, font); TRACE("%p, %d, %d, %d, %p.\n", iface, weight, stretch, style, font);
if (This->data->font_count == 0) { if (!family->data->count)
{
*font = NULL; *font = NULL;
return DWRITE_E_NOFONT; return DWRITE_E_NOFONT;
} }
@ -2129,12 +2134,13 @@ static HRESULT WINAPI dwritefontfamily_GetFirstMatchingFont(IDWriteFontFamily1 *
init_font_prop_vec(weight, stretch, style, &req); init_font_prop_vec(weight, stretch, style, &req);
match = 0; match = 0;
for (i = 1; i < This->data->font_count; i++) { for (i = 1; i < family->data->count; ++i)
if (is_better_font_match(&This->data->fonts[i]->propvec, &This->data->fonts[match]->propvec, &req)) {
if (is_better_font_match(&family->data->fonts[i]->propvec, &family->data->fonts[match]->propvec, &req))
match = i; match = i;
} }
return create_font(This, match, (IDWriteFont3 **)font); return create_font(family, match, (IDWriteFont3 **)font);
} }
typedef BOOL (*matching_filter_func)(const struct dwrite_font_data*); typedef BOOL (*matching_filter_func)(const struct dwrite_font_data*);
@ -2174,13 +2180,13 @@ static void matchingfonts_sort(struct dwrite_fontlist *fonts, const struct dwrit
static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *iface, DWRITE_FONT_WEIGHT weight, static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *iface, DWRITE_FONT_WEIGHT weight,
DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontList **ret) DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFontList **ret)
{ {
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily1(iface); struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily1(iface);
matching_filter_func func = NULL; matching_filter_func func = NULL;
struct dwrite_font_propvec req; struct dwrite_font_propvec req;
struct dwrite_fontlist *fonts; struct dwrite_fontlist *fonts;
UINT32 i; size_t i;
TRACE("(%p)->(%d %d %d %p)\n", This, weight, stretch, style, ret); TRACE("%p, %d, %d, %d, %p.\n", iface, weight, stretch, style, ret);
*ret = NULL; *ret = NULL;
@ -2189,7 +2195,7 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *ifac
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
/* Allocate as many as family has, not all of them will be necessary used. */ /* Allocate as many as family has, not all of them will be necessary used. */
fonts->fonts = heap_calloc(This->data->font_count, sizeof(*fonts->fonts)); fonts->fonts = heap_calloc(family->data->count, sizeof(*fonts->fonts));
if (!fonts->fonts) { if (!fonts->fonts) {
heap_free(fonts); heap_free(fonts);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
@ -2197,24 +2203,26 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *ifac
fonts->IDWriteFontList1_iface.lpVtbl = &dwritefontlistvtbl; fonts->IDWriteFontList1_iface.lpVtbl = &dwritefontlistvtbl;
fonts->ref = 1; fonts->ref = 1;
fonts->family = This; fonts->family = family;
IDWriteFontFamily1_AddRef(&fonts->family->IDWriteFontFamily1_iface); IDWriteFontFamily1_AddRef(&fonts->family->IDWriteFontFamily1_iface);
fonts->font_count = 0; fonts->font_count = 0;
/* Normal style accepts Normal or Italic, Oblique and Italic - both Oblique and Italic styles */ /* Normal style accepts Normal or Italic, Oblique and Italic - both Oblique and Italic styles */
if (style == DWRITE_FONT_STYLE_NORMAL) { if (style == DWRITE_FONT_STYLE_NORMAL) {
if (This->data->has_normal_face || This->data->has_italic_face) if (family->data->has_normal_face || family->data->has_italic_face)
func = is_font_acceptable_for_normal; func = is_font_acceptable_for_normal;
} }
else /* requested oblique or italic */ { else /* requested oblique or italic */ {
if (This->data->has_oblique_face || This->data->has_italic_face) if (family->data->has_oblique_face || family->data->has_italic_face)
func = is_font_acceptable_for_oblique_italic; func = is_font_acceptable_for_oblique_italic;
} }
for (i = 0; i < This->data->font_count; i++) { for (i = 0; i < family->data->count; ++i)
if (!func || func(This->data->fonts[i])) { {
fonts->fonts[fonts->font_count] = This->data->fonts[i]; if (!func || func(family->data->fonts[i]))
addref_font_data(This->data->fonts[i]); {
fonts->fonts[fonts->font_count] = family->data->fonts[i];
addref_font_data(family->data->fonts[i]);
fonts->font_count++; fonts->font_count++;
} }
} }
@ -2223,7 +2231,7 @@ static HRESULT WINAPI dwritefontfamily_GetMatchingFonts(IDWriteFontFamily1 *ifac
init_font_prop_vec(weight, stretch, style, &req); init_font_prop_vec(weight, stretch, style, &req);
matchingfonts_sort(fonts, &req); matchingfonts_sort(fonts, &req);
*ret = (IDWriteFontList*)&fonts->IDWriteFontList1_iface; *ret = (IDWriteFontList *)&fonts->IDWriteFontList1_iface;
return S_OK; return S_OK;
} }
@ -2238,19 +2246,19 @@ static DWRITE_LOCALITY WINAPI dwritefontfamily1_GetFontLocality(IDWriteFontFamil
static HRESULT WINAPI dwritefontfamily1_GetFont(IDWriteFontFamily1 *iface, UINT32 index, IDWriteFont3 **font) static HRESULT WINAPI dwritefontfamily1_GetFont(IDWriteFontFamily1 *iface, UINT32 index, IDWriteFont3 **font)
{ {
struct dwrite_fontfamily *This = impl_from_IDWriteFontFamily1(iface); struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily1(iface);
TRACE("(%p)->(%u %p)\n", This, index, font); TRACE("%p, %u, %p.\n", iface, index, font);
*font = NULL; *font = NULL;
if (This->data->font_count == 0) if (!family->data->count)
return S_FALSE; return S_FALSE;
if (index >= This->data->font_count) if (index >= family->data->count)
return E_FAIL; return E_FAIL;
return create_font(This, index, font); return create_font(family, index, font);
} }
static HRESULT WINAPI dwritefontfamily1_GetFontFaceReference(IDWriteFontFamily1 *iface, UINT32 index, static HRESULT WINAPI dwritefontfamily1_GetFontFaceReference(IDWriteFontFamily1 *iface, UINT32 index,
@ -2359,22 +2367,23 @@ static const IDWriteFontList1Vtbl fontfamilylistvtbl = {
static HRESULT create_fontfamily(struct dwrite_fontcollection *collection, UINT32 index, IDWriteFontFamily1 **family) static HRESULT create_fontfamily(struct dwrite_fontcollection *collection, UINT32 index, IDWriteFontFamily1 **family)
{ {
struct dwrite_fontfamily *This; struct dwrite_fontfamily *object;
*family = NULL; *family = NULL;
This = heap_alloc(sizeof(struct dwrite_fontfamily)); object = heap_alloc(sizeof(*object));
if (!This) return E_OUTOFMEMORY; if (!object)
return E_OUTOFMEMORY;
This->IDWriteFontFamily1_iface.lpVtbl = &fontfamilyvtbl; object->IDWriteFontFamily1_iface.lpVtbl = &fontfamilyvtbl;
This->IDWriteFontList1_iface.lpVtbl = &fontfamilylistvtbl; object->IDWriteFontList1_iface.lpVtbl = &fontfamilylistvtbl;
This->ref = 1; object->ref = 1;
This->collection = collection; object->collection = collection;
IDWriteFontCollection1_AddRef(&collection->IDWriteFontCollection1_iface); IDWriteFontCollection1_AddRef(&collection->IDWriteFontCollection1_iface);
This->data = collection->family_data[index]; object->data = collection->family_data[index];
InterlockedIncrement(&This->data->ref); InterlockedIncrement(&object->data->refcount);
*family = &This->IDWriteFontFamily1_iface; *family = &object->IDWriteFontFamily1_iface;
return S_OK; return S_OK;
} }
@ -2535,10 +2544,11 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
{ {
struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection1(iface); struct dwrite_fontcollection *This = impl_from_IDWriteFontCollection1(iface);
IDWriteFontFamily1 *family; IDWriteFontFamily1 *family;
UINT32 i, j, face_index;
BOOL found_font = FALSE; BOOL found_font = FALSE;
IDWriteFontFile *file; IDWriteFontFile *file;
UINT32 i, face_index;
HRESULT hr; HRESULT hr;
size_t j;
TRACE("(%p)->(%p %p)\n", This, face, font); TRACE("(%p)->(%p %p)\n", This, face, font);
@ -2557,7 +2567,8 @@ static HRESULT WINAPI dwritefontcollection_GetFontFromFontFace(IDWriteFontCollec
for (i = 0; i < This->family_count; i++) { for (i = 0; i < This->family_count; i++) {
struct dwrite_fontfamily_data *family_data = This->family_data[i]; struct dwrite_fontfamily_data *family_data = This->family_data[i];
for (j = 0; j < family_data->font_count; j++) { for (j = 0; j < family_data->count; ++j)
{
struct dwrite_font_data *font_data = family_data->fonts[j]; struct dwrite_font_data *font_data = family_data->fonts[j];
if (face_index == font_data->face_index && is_same_fontfile(file, font_data->file)) { if (face_index == font_data->face_index && is_same_fontfile(file, font_data->file)) {
@ -2632,20 +2643,13 @@ static const IDWriteFontCollection1Vtbl systemfontcollectionvtbl = {
static HRESULT fontfamily_add_font(struct dwrite_fontfamily_data *family_data, struct dwrite_font_data *font_data) static HRESULT fontfamily_add_font(struct dwrite_fontfamily_data *family_data, struct dwrite_font_data *font_data)
{ {
if (family_data->font_count + 1 >= family_data->font_alloc) { if (!dwrite_array_reserve((void **)&family_data->fonts, &family_data->size, family_data->count + 1,
struct dwrite_font_data **new_list; sizeof(*family_data->fonts)))
UINT32 new_alloc; {
return E_OUTOFMEMORY;
new_alloc = family_data->font_alloc * 2;
new_list = heap_realloc(family_data->fonts, sizeof(*family_data->fonts) * new_alloc);
if (!new_list)
return E_OUTOFMEMORY;
family_data->fonts = new_list;
family_data->font_alloc = new_alloc;
} }
family_data->fonts[family_data->font_count] = font_data; family_data->fonts[family_data->count++] = font_data;
family_data->font_count++;
if (font_data->style == DWRITE_FONT_STYLE_NORMAL) if (font_data->style == DWRITE_FONT_STYLE_NORMAL)
family_data->has_normal_face = 1; family_data->has_normal_face = 1;
else if (font_data->style == DWRITE_FONT_STYLE_OBLIQUE) else if (font_data->style == DWRITE_FONT_STYLE_OBLIQUE)
@ -3518,35 +3522,25 @@ static HRESULT init_fontfamily_data(IDWriteLocalizedStrings *familyname, struct
{ {
struct dwrite_fontfamily_data *data; struct dwrite_fontfamily_data *data;
data = heap_alloc(sizeof(*data)); data = heap_alloc_zero(sizeof(*data));
if (!data) if (!data)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
data->ref = 1; data->refcount = 1;
data->font_count = 0;
data->font_alloc = 2;
data->has_normal_face = 0;
data->has_oblique_face = 0;
data->has_italic_face = 0;
data->fonts = heap_calloc(data->font_alloc, sizeof(*data->fonts));
if (!data->fonts) {
heap_free(data);
return E_OUTOFMEMORY;
}
data->familyname = familyname; data->familyname = familyname;
IDWriteLocalizedStrings_AddRef(familyname); IDWriteLocalizedStrings_AddRef(familyname);
*ret = data; *ret = data;
return S_OK; return S_OK;
} }
static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *family) static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *family)
{ {
UINT32 i, j, heaviest; size_t i, j, heaviest;
for (i = 0; i < family->font_count; i++) { for (i = 0; i < family->count; ++i)
{
DWRITE_FONT_WEIGHT weight = family->fonts[i]->weight; DWRITE_FONT_WEIGHT weight = family->fonts[i]->weight;
heaviest = i; heaviest = i;
@ -3554,7 +3548,8 @@ static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *fa
continue; continue;
family->fonts[i]->bold_sim_tested = 1; family->fonts[i]->bold_sim_tested = 1;
for (j = i; j < family->font_count; j++) { for (j = i; j < family->count; ++j)
{
if (family->fonts[j]->bold_sim_tested) if (family->fonts[j]->bold_sim_tested)
continue; continue;
@ -3616,9 +3611,10 @@ static void fontfamily_add_bold_simulated_face(struct dwrite_fontfamily_data *fa
static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data *family) static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data *family)
{ {
UINT32 i, j; size_t i, j;
for (i = 0; i < family->font_count; i++) { for (i = 0; i < family->count; ++i)
{
UINT32 regular = ~0u, oblique = ~0u; UINT32 regular = ~0u, oblique = ~0u;
struct dwrite_font_data *obliqueface; struct dwrite_font_data *obliqueface;
WCHAR facenameW[255]; WCHAR facenameW[255];
@ -3633,7 +3629,8 @@ static void fontfamily_add_oblique_simulated_face(struct dwrite_fontfamily_data
oblique = i; oblique = i;
/* find regular style with same weight/stretch values */ /* find regular style with same weight/stretch values */
for (j = i; j < family->font_count; j++) { for (j = i; j < family->count; ++j)
{
if (family->fonts[j]->oblique_sim_tested) if (family->fonts[j]->oblique_sim_tested)
continue; continue;
@ -3701,7 +3698,8 @@ static BOOL fontcollection_add_replacement(struct dwrite_fontcollection *collect
struct dwrite_fontfamily_data *replacement = collection->family_data[i]; struct dwrite_fontfamily_data *replacement = collection->family_data[i];
WCHAR nameW[255]; WCHAR nameW[255];
for (i = 0; i < replacement->font_count; i++) { for (i = 0; i < replacement->count; ++i)
{
fontfamily_add_font(target, replacement->fonts[i]); fontfamily_add_font(target, replacement->fonts[i]);
addref_font_data(replacement->fonts[i]); addref_font_data(replacement->fonts[i]);
} }