[PATCH 3/5] gdi32: Update the external keys after all fonts are loaded.

Rémi Bernon rbernon at codeweavers.com
Fri Nov 27 08:38:03 CST 2020


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

The new ADDFONT_EXTERNAL_FOUND flag is here to indicate that a font was
found in the external key, and that its path doesn't need an update.

 dlls/gdi32/font.c        | 98 +++++++++++++---------------------------
 dlls/gdi32/gdi_private.h |  1 +
 2 files changed, 33 insertions(+), 66 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 7338d5fbb03..d3202d83a15 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -7812,70 +7812,57 @@ static void load_file_system_fonts(void)
 
 struct external_key
 {
-    struct wine_rb_entry entry;
-    BOOL                 found;
-    WCHAR                value[LF_FULLFACESIZE + 12];
-    WCHAR                path[1];
+    struct list entry;
+    WCHAR       value[LF_FULLFACESIZE + 12];
 };
 
-static int compare_external_key( const void *key, const struct wine_rb_entry *entry )
+static void update_external_font_keys(void)
 {
-    return facename_compare( key, WINE_RB_ENTRY_VALUE( entry, struct external_key, entry )->value, -1 );
-}
+    struct list external_keys = LIST_INIT(external_keys);
+    HKEY winnt_key = 0, win9x_key = 0;
+    struct gdi_font_family *family;
+    struct external_key *key, *next;
+    struct gdi_font_face *face;
+    DWORD len, i = 0, type, dlen, vlen;
+    WCHAR value[LF_FULLFACESIZE + 12], path[MAX_PATH], *tmp;
+    WCHAR *file;
+    HKEY hkey;
 
-static struct wine_rb_tree external_keys = { compare_external_key };
+    RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
+                     0, NULL, 0, KEY_ALL_ACCESS, NULL, &winnt_key, NULL );
+    RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts",
+                     0, NULL, 0, KEY_ALL_ACCESS, NULL, &win9x_key, NULL );
 
-static HKEY load_external_font_keys(void)
-{
-    WCHAR value[LF_FULLFACESIZE + 12], path[MAX_PATH];
-    DWORD i = 0, type, dlen, vlen;
-    struct external_key *key;
-    HKEY hkey;
+    /* enumerate the fonts and add external ones to the two keys */
 
-    if (RegCreateKeyW( wine_fonts_key, L"External Fonts", &hkey )) return 0;
+    if (RegCreateKeyW( wine_fonts_key, L"External Fonts", &hkey )) return;
 
     vlen = ARRAY_SIZE(value);
     dlen = sizeof(path);
     while (!RegEnumValueW( hkey, i++, value, &vlen, NULL, &type, (BYTE *)path, &dlen ))
     {
         if (type != REG_SZ) goto next;
-        dlen /= sizeof(WCHAR);
-        if (!(key = HeapAlloc( GetProcessHeap(), 0, offsetof(struct external_key, path[dlen]) ))) break;
-        key->found = FALSE;
+        if ((tmp = wcsrchr( value, ' ' )) && !facename_compare( tmp, L" (TrueType)", -1 )) *tmp = 0;
+        if ((face = find_face_from_full_name( value )))
+        {
+            if (!wcsicmp( face->file, path )) face->flags |= ADDFONT_EXTERNAL_FOUND;
+            goto next;
+        }
+        if (tmp && !*tmp) *tmp = ' ';
+        if (!(key = HeapAlloc( GetProcessHeap(), 0, sizeof(*key) ))) break;
         lstrcpyW( key->value, value );
-        lstrcpyW( key->path, path );
-        wine_rb_put( &external_keys, value, &key->entry );
+        list_add_tail( &external_keys, &key->entry );
     next:
         vlen = ARRAY_SIZE(value);
         dlen = sizeof(path);
     }
-    return hkey;
-}
-
-static void update_external_font_keys( HKEY hkey )
-{
-    HKEY winnt_key = 0, win9x_key = 0;
-    struct gdi_font_family *family;
-    struct gdi_font_face *face;
-    struct wine_rb_entry *entry;
-    struct external_key *key, *next;
-    DWORD len;
-    BOOL skip;
-    WCHAR value[LF_FULLFACESIZE + 12], path[MAX_PATH];
-    WCHAR *file;
-
-    RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
-                     0, NULL, 0, KEY_ALL_ACCESS, NULL, &winnt_key, NULL );
-    RegCreateKeyExW( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Fonts",
-                     0, NULL, 0, KEY_ALL_ACCESS, NULL, &win9x_key, NULL );
-
-    /* enumerate the fonts and add external ones to the two keys */
 
     WINE_RB_FOR_EACH_ENTRY( family, &family_name_tree, struct gdi_font_family, name_entry )
     {
         LIST_FOR_EACH_ENTRY( face, &family->faces, struct gdi_font_face, entry )
         {
             if (!(face->flags & ADDFONT_EXTERNAL_FONT)) continue;
+            if ((face->flags & ADDFONT_EXTERNAL_FOUND)) continue;
 
             lstrcpyW( value, face->full_name );
             if (face->scalable) lstrcatW( value, L" (TrueType)" );
@@ -7887,38 +7874,29 @@ static void update_external_font_keys( HKEY hkey )
             else
                 file = face->file;
 
-            skip = FALSE;
-            if ((entry = wine_rb_get( &external_keys, value )))
-            {
-                struct external_key *key = WINE_RB_ENTRY_VALUE( entry, struct external_key, entry );
-                skip = key->found && !wcsicmp( key->path, file );
-                wine_rb_remove_key( &external_keys, value );
-                HeapFree( GetProcessHeap(), 0, key );
-            }
-            if (skip) continue;
             len = (lstrlenW(file) + 1) * sizeof(WCHAR);
             RegSetValueExW( winnt_key, value, 0, REG_SZ, (BYTE *)file, len );
             RegSetValueExW( win9x_key, value, 0, REG_SZ, (BYTE *)file, len );
             RegSetValueExW( hkey, value, 0, REG_SZ, (BYTE *)file, len );
         }
     }
-    WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR( key, next, &external_keys, struct external_key, entry )
+    LIST_FOR_EACH_ENTRY_SAFE( key, next, &external_keys, struct external_key, entry )
     {
         RegDeleteValueW( win9x_key, key->value );
         RegDeleteValueW( winnt_key, key->value );
         RegDeleteValueW( hkey, key->value );
-        wine_rb_remove_key( &external_keys, key->value );
+        list_remove( &key->entry );
         HeapFree( GetProcessHeap(), 0, key );
     }
     RegCloseKey( win9x_key );
     RegCloseKey( winnt_key );
+    RegCloseKey( hkey );
 }
 
 static void load_registry_fonts(void)
 {
     WCHAR value[LF_FULLFACESIZE + 12], data[MAX_PATH], *tmp;
     DWORD i = 0, type, dlen, vlen;
-    struct wine_rb_entry *entry;
     HKEY hkey;
 
     /* Look under HKLM\Software\Microsoft\Windows[ NT]\CurrentVersion\Fonts
@@ -7936,16 +7914,6 @@ static void load_registry_fonts(void)
     {
         if (type != REG_SZ) goto next;
         dlen /= sizeof(WCHAR);
-        if ((entry = wine_rb_get( &external_keys, value )))
-        {
-            struct external_key *key = WINE_RB_ENTRY_VALUE( entry, struct external_key, entry );
-            if (!wcsicmp( key->path, data ))
-            {
-                key->found = TRUE;
-                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 = ' ';
@@ -7987,13 +7955,11 @@ void font_init(void)
 
     if (disposition == REG_CREATED_NEW_KEY)
     {
-        HKEY key = load_external_font_keys();
         load_system_bitmap_fonts();
         load_file_system_fonts();
         font_funcs->load_fonts();
         load_registry_fonts();
-        update_external_font_keys( key );
-        RegCloseKey( key );
+        update_external_font_keys();
     }
     else load_font_list_from_cache();
 
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 163152fe839..b9a06415538 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -376,6 +376,7 @@ struct gdi_font
 #define ADDFONT_ADD_TO_CACHE  0x04
 #define ADDFONT_ADD_RESOURCE  0x08  /* added through AddFontResource */
 #define ADDFONT_VERTICAL_FONT 0x10
+#define ADDFONT_EXTERNAL_FOUND 0x20
 #define ADDFONT_AA_FLAGS(flags) ((flags) << 16)
 
 struct font_backend_funcs
-- 
2.29.2




More information about the wine-devel mailing list