gdi32: Index scalable faces by full name in rbtree.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2020-11-27 15:38:02 +01:00 committed by Alexandre Julliard
parent 3c0137f81e
commit 7f4a889078
1 changed files with 33 additions and 1 deletions

View File

@ -83,6 +83,7 @@ struct gdi_font_face
struct bitmap_font_size size; /* set if face is a bitmap */
struct gdi_font_family *family;
struct gdi_font_enum_data *cached_enum_data;
struct wine_rb_entry full_name_entry;
};
static const struct font_backend_funcs *font_funcs;
@ -583,8 +584,20 @@ static int family_second_name_compare( const void *key, const struct wine_rb_ent
return family_namecmp( (const WCHAR *)key, family->second_name );
}
static int face_full_name_compare( const void *key, const struct wine_rb_entry *entry )
{
const struct gdi_font_face *face = WINE_RB_ENTRY_VALUE( entry, const struct gdi_font_face, full_name_entry );
return facename_compare( (const WCHAR *)key, face->full_name, LF_FULLFACESIZE - 1 );
}
static struct wine_rb_tree family_name_tree = { family_name_compare };
static struct wine_rb_tree family_second_name_tree = { family_second_name_compare };
static struct wine_rb_tree face_full_name_tree = { face_full_name_compare };
static int face_is_in_full_name_tree( const struct gdi_font_face *face )
{
return face->full_name_entry.parent || face_full_name_tree.root == &face->full_name_entry;
}
static struct gdi_font_family *create_family( const WCHAR *name, const WCHAR *second_name )
{
@ -631,6 +644,13 @@ static struct gdi_font_family *find_family_from_any_name( const WCHAR *name )
return WINE_RB_ENTRY_VALUE( entry, struct gdi_font_family, second_name_entry );
}
static struct gdi_font_face *find_face_from_full_name( const WCHAR *full_name )
{
struct wine_rb_entry *entry;
if (!(entry = wine_rb_get( &face_full_name_tree, full_name ))) return NULL;
return WINE_RB_ENTRY_VALUE( entry, struct gdi_font_face, full_name_entry );
}
static const struct list *get_family_face_list( const struct gdi_font_family *family )
{
return family->replacement ? &family->replacement->faces : &family->faces;
@ -819,6 +839,7 @@ static void release_face( struct gdi_font_face *face )
list_remove( &face->entry );
release_family( face->family );
}
if (face_is_in_full_name_tree( face )) wine_rb_remove( &face_full_name_tree, &face->full_name_entry );
HeapFree( GetProcessHeap(), 0, face->file );
HeapFree( GetProcessHeap(), 0, face->style_name );
HeapFree( GetProcessHeap(), 0, face->full_name );
@ -913,6 +934,11 @@ static BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_f
face->family = family;
family->refcount++;
face->refcount++;
if (face_is_in_full_name_tree( cursor ))
{
wine_rb_replace( &face_full_name_tree, &cursor->full_name_entry, &face->full_name_entry );
memset( &cursor->full_name_entry, 0, sizeof(cursor->full_name_entry) );
}
release_face( cursor );
return TRUE;
}
@ -923,6 +949,7 @@ static BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_f
TRACE( "Adding face %s in family %s from %s\n", debugstr_w(face->full_name),
debugstr_w(family->family_name), debugstr_w(face->file) );
list_add_before( &cursor->entry, &face->entry );
if (face->scalable) wine_rb_put( &face_full_name_tree, face->full_name, &face->full_name_entry );
face->family = family;
family->refcount++;
face->refcount++;
@ -7889,7 +7916,7 @@ static void update_external_font_keys( HKEY hkey )
static void load_registry_fonts(void)
{
WCHAR value[LF_FULLFACESIZE + 12], data[MAX_PATH];
WCHAR value[LF_FULLFACESIZE + 12], data[MAX_PATH], *tmp;
DWORD i = 0, type, dlen, vlen;
struct wine_rb_entry *entry;
HKEY hkey;
@ -7918,6 +7945,11 @@ static void load_registry_fonts(void)
goto next;
}
}
if ((tmp = wcsrchr( value, ' ' )) && !facename_compare( tmp, L" (TrueType)", -1 )) *tmp = 0;
if (find_face_from_full_name( value )) goto next;
if (tmp && !*tmp) *tmp = ' ';
if (data[0] && data[1] == ':')
add_font_resource( data, ADDFONT_ALLOW_BITMAP | ADDFONT_ADD_TO_CACHE );
else if (dlen >= 6 && !wcsicmp( data + dlen - 5, L".fon" ))