gdi32: Add ref counting to the face and family objects.

This commit is contained in:
Alexandre Julliard 2013-01-14 15:19:14 +01:00
parent 634840579c
commit 865078b05a
1 changed files with 50 additions and 33 deletions

View File

@ -259,6 +259,7 @@ struct enum_data
typedef struct tagFace {
struct list entry;
unsigned int refcount;
WCHAR *StyleName;
WCHAR *FullName;
WCHAR *file;
@ -280,6 +281,7 @@ typedef struct tagFace {
typedef struct tagFamily {
struct list entry;
unsigned int refcount;
WCHAR *FamilyName;
WCHAR *EnglishName;
struct list faces;
@ -966,7 +968,9 @@ static Face *find_face_from_filename(const WCHAR *file_name, const WCHAR *face_n
file = face->file;
else
file++;
if(!strcmpiW(file, file_name)) return face;
if(strcmpiW(file, file_name)) continue;
face->refcount++;
return face;
}
}
return NULL;
@ -1233,8 +1237,24 @@ static inline BOOL faces_equal( const Face *f1, const Face *f2 )
return !memcmp( &f1->fs, &f2->fs, sizeof(f1->fs) );
}
static inline void free_face( Face *face )
static void release_family( Family *family )
{
if (--family->refcount) return;
assert( list_empty( &family->faces ));
list_remove( &family->entry );
HeapFree( GetProcessHeap(), 0, family->FamilyName );
HeapFree( GetProcessHeap(), 0, family->EnglishName );
HeapFree( GetProcessHeap(), 0, family );
}
static void release_face( Face *face )
{
if (--face->refcount) return;
if (face->family)
{
list_remove( &face->entry );
release_family( face->family );
}
HeapFree( GetProcessHeap(), 0, face->file );
HeapFree( GetProcessHeap(), 0, face->StyleName );
HeapFree( GetProcessHeap(), 0, face->FullName );
@ -1242,20 +1262,6 @@ static inline void free_face( Face *face )
HeapFree( GetProcessHeap(), 0, face );
}
static inline void free_family( Family *family )
{
Face *face, *cursor2;
LIST_FOR_EACH_ENTRY_SAFE( face, cursor2, &family->faces, Face, entry )
{
list_remove( &face->entry );
free_face( face );
}
HeapFree( GetProcessHeap(), 0, family->FamilyName );
HeapFree( GetProcessHeap(), 0, family->EnglishName );
HeapFree( GetProcessHeap(), 0, family );
}
static inline int style_order(const Face *face)
{
switch (face->ntmFlags & (NTM_REGULAR | NTM_BOLD | NTM_ITALIC))
@ -1301,8 +1307,9 @@ static BOOL insert_face_in_family_list( Face *face, Family *family )
debugstr_w(cursor->file), debugstr_w(face->file));
list_add_before( &cursor->entry, &face->entry );
face->family = family;
list_remove( &cursor->entry);
free_face( cursor );
family->refcount++;
face->refcount++;
release_face( cursor );
return TRUE;
}
}
@ -1314,6 +1321,8 @@ static BOOL insert_face_in_family_list( Face *face, Family *family )
list_add_before( &cursor->entry, &face->entry );
face->family = family;
family->refcount++;
face->refcount++;
return TRUE;
}
@ -1324,10 +1333,12 @@ static BOOL insert_face_in_family_list( Face *face, Family *family )
static Family *create_family( WCHAR *name, WCHAR *english_name )
{
Family * const family = HeapAlloc( GetProcessHeap(), 0, sizeof(*family) );
family->refcount = 1;
family->FamilyName = name;
family->EnglishName = english_name;
list_init( &family->faces );
family->replacement = &family->faces;
list_add_tail( &font_list, &family->entry );
return family;
}
@ -1363,7 +1374,9 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu
Face *face;
face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
face->cached_enum_data = NULL;
face->family = NULL;
face->refcount = 1;
face->file = strdupW( buffer );
face->StyleName = strdupW(face_name);
@ -1406,9 +1419,10 @@ static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family, void *bu
face->fs.fsUsb[0], face->fs.fsUsb[1],
face->fs.fsUsb[2], face->fs.fsUsb[3]);
insert_face_in_family_list(face, family);
if (insert_face_in_family_list(face, family))
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), debugstr_w(face->StyleName));
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), debugstr_w(face->StyleName));
release_face( face );
}
/* load bitmap strikes */
@ -1446,7 +1460,6 @@ static void load_font_list_from_cache(HKEY hkey_font_cache)
english_family = strdupW( buffer );
family = create_family(family_name, english_family);
list_add_tail(&font_list, &family->entry);
if(english_family)
{
@ -1473,6 +1486,7 @@ static void load_font_list_from_cache(HKEY hkey_font_cache)
size = sizeof(buffer);
}
RegCloseKey(hkey_family);
release_family( family );
size = sizeof(buffer);
}
}
@ -1601,8 +1615,6 @@ static Family *get_family( FT_Face ft_face, BOOL vertical )
if (!family)
{
family = create_family( name, english_name );
list_add_tail( &font_list, &family->entry );
if (english_name)
{
FontSubst *subst = HeapAlloc( GetProcessHeap(), 0, sizeof(*subst) );
@ -1617,6 +1629,7 @@ static Family *get_family( FT_Face ft_face, BOOL vertical )
{
HeapFree( GetProcessHeap(), 0, name );
HeapFree( GetProcessHeap(), 0, english_name );
family->refcount++;
}
return family;
@ -1733,6 +1746,7 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file,
Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
My_FT_Bitmap_Size *size = (My_FT_Bitmap_Size *)ft_face->available_sizes;
face->refcount = 1;
face->StyleName = get_face_name( ft_face, TT_NAME_ID_FONT_SUBFAMILY, GetSystemDefaultLangID() );
if (!face->StyleName)
face->StyleName = get_face_name( ft_face, TT_NAME_ID_FONT_SUBFAMILY, TT_MS_LANGID_ENGLISH_UNITED_STATES );
@ -1806,17 +1820,16 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr
face = create_face( ft_face, face_index, file, font_data_ptr, font_data_size, flags, vertical, aa_flags );
family = get_family( ft_face, vertical );
if (!insert_face_in_family_list( face, family ))
if (insert_face_in_family_list( face, family ))
{
free_face( face );
return;
if (flags & ADDFONT_ADD_TO_CACHE)
add_face_to_cache( face );
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
debugstr_w(face->StyleName));
}
if (flags & ADDFONT_ADD_TO_CACHE)
add_face_to_cache( face );
TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
debugstr_w(face->StyleName));
release_face( face );
release_family( family );
}
static FT_Face new_ft_face( const char *file, void *font_data_ptr, DWORD font_data_size,
@ -2323,6 +2336,7 @@ skip_internal:
new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
new_child->face = font_link_entry->face;
new_child->font = NULL;
new_child->face->refcount++;
system_font_link->fs.fsCsb[0] |= font_link_entry->face->fs.fsCsb[0];
system_font_link->fs.fsCsb[1] |= font_link_entry->face->fs.fsCsb[1];
list_add_tail(&system_font_link->links, &new_child->entry);
@ -3001,7 +3015,7 @@ static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
pFT_Done_Face( ft_face );
GetEnumStructs( face, name, &elf, &ntm, &type );
free_face( face );
release_face( face );
HeapFree( GetProcessHeap(), 0, name );
HeapFree( GetProcessHeap(), 0, english_name );
@ -4042,6 +4056,7 @@ static void free_font(GdiFont *font)
list_remove(&child->entry);
if(child->font)
free_font(child->font);
release_face( child->face );
HeapFree(GetProcessHeap(), 0, child);
}
@ -4354,6 +4369,7 @@ static BOOL create_child_font_list(GdiFont *font)
new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
new_child->face = font_link_entry->face;
new_child->font = NULL;
new_child->face->refcount++;
list_add_tail(&font->child_fonts, &new_child->entry);
TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
}
@ -4376,6 +4392,7 @@ static BOOL create_child_font_list(GdiFont *font)
new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
new_child->face = font_link_entry->face;
new_child->font = NULL;
new_child->face->refcount++;
list_add_tail(&font->child_fonts, &new_child->entry);
TRACE("font %s %ld\n", debugstr_w(new_child->face->file), new_child->face->face_index);
}