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