Rémi Bernon : gdi32: Index scalable faces by full name in rbtree.
Alexandre Julliard
julliard at winehq.org
Tue Dec 1 15:40:34 CST 2020
Module: wine
Branch: master
Commit: 7f4a8890784bea82a97f715339aa8ffd64c391f7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7f4a8890784bea82a97f715339aa8ffd64c391f7
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Fri Nov 27 15:38:02 2020 +0100
gdi32: Index scalable faces by full name in rbtree.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/gdi32/font.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 28179aec54a..7338d5fbb03 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -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" ))
More information about the wine-cvs
mailing list