gdi32: Add ref counting to the face and family objects.
This commit is contained in:
parent
634840579c
commit
865078b05a
|
@ -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));
|
||||
|
||||
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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue