79633: [PATCH 4/5] gdi32: Load the font properties from the cache if it exists.

buildbot at kegel.com buildbot at kegel.com
Thu Oct 6 19:51:21 CDT 2011


This is an experimental automated build and test service.
Please feel free to ignore this email while we work the kinks out.

For more info about this message, see http://wiki.winehq.org/BuildBot

The Buildbot has detected a failed build on builder runtests-default while building Wine.
Full details are available at: http://buildbot.kegel.com/builders/runtests-default/builds/36 (though maybe not for long, as I'm still reinstalling the buildbot periodically while experimenting)
BUILD FAILED: failed git

Errors:
error: patch failed: dlls/gdi32/freetype.c:282
error: dlls/gdi32/freetype.c: patch does not apply
error: patch failed: dlls/gdi32/freetype.c:2745
error: dlls/gdi32/freetype.c: patch does not apply
error: patch failed: dlls/gdi32/freetype.c:472
error: dlls/gdi32/freetype.c: patch does not apply
error: patch failed: dlls/gdi32/freetype.c:1145
error: dlls/gdi32/freetype.c: patch does not apply

-------------- next part --------------
From: Huw Davies <huw at codeweavers.com>
Subject: [PATCH 1/5] gdi32: Keep track of the english family name if there's a localised name as well.
Message-Id: <1317936368-4103-1-git-send-email-huw at codeweavers.com>
Date: Thu,  6 Oct 2011 16:26:04 -0500

---
 dlls/gdi32/freetype.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 81c704b..ae8ca41 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -282,6 +282,7 @@ typedef struct tagFace {
 typedef struct tagFamily {
     struct list entry;
     const WCHAR *FamilyName;
+    const WCHAR *EnglishName;
     struct list faces;
 } Family;
 
@@ -1378,6 +1379,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             if(!family) {
                 family = HeapAlloc(GetProcessHeap(), 0, sizeof(*family));
                 family->FamilyName = strdupW(localised_family ? localised_family : english_family);
+                family->EnglishName = localised_family ? strdupW(english_family) : NULL;
                 list_init(&family->faces);
                 list_add_tail(&font_list, &family->entry);
 

From: Huw Davies <huw at codeweavers.com>
Subject: [PATCH 2/5] gdi32: Move the font list initialisation to a separate function.
Message-Id: <1317936368-4103-2-git-send-email-huw at codeweavers.com>
Date: Thu,  6 Oct 2011 16:26:05 -0500

---
 dlls/gdi32/freetype.c |   64 +++++++++++++++++++++++++++---------------------
 1 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index ae8ca41..62c0504 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -2745,12 +2745,7 @@ sym_not_found:
     return FALSE;
 }
 
-/*************************************************************
- *    WineEngInit
- *
- * Initialize FreeType library and create a list of available faces
- */
-BOOL WineEngInit(void)
+static void init_font_list(void)
 {
     static const WCHAR dot_fonW[] = {'.','f','o','n','\0'};
     static const WCHAR pathW[] = {'P','a','t','h',0};
@@ -2758,22 +2753,8 @@ BOOL WineEngInit(void)
     DWORD valuelen, datalen, i = 0, type, dlen, vlen;
     WCHAR windowsdir[MAX_PATH];
     char *unixname;
-    HANDLE font_mutex;
     const char *data_dir;
 
-    TRACE("\n");
-
-    /* update locale dependent font info in registry */
-    update_font_info();
-
-    if(!init_freetype()) return FALSE;
-
-    if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL) {
-        ERR("Failed to create font mutex\n");
-        return FALSE;
-    }
-    WaitForSingleObject(font_mutex, INFINITE);
-
     delete_external_font_keys();
 
     /* load the system bitmap fonts */
@@ -2791,7 +2772,8 @@ BOOL WineEngInit(void)
     /* load the system truetype fonts */
     data_dir = wine_get_data_dir();
     if (!data_dir) data_dir = wine_get_build_dir();
-    if (data_dir && (unixname = HeapAlloc(GetProcessHeap(), 0, strlen(data_dir) + sizeof("/fonts/")))) {
+    if (data_dir && (unixname = HeapAlloc(GetProcessHeap(), 0, strlen(data_dir) + sizeof("/fonts/"))))
+    {
         strcpy(unixname, data_dir);
         strcat(unixname, "/fonts/");
         ReadFontDir(unixname, TRUE);
@@ -2804,20 +2786,22 @@ BOOL WineEngInit(void)
        will skip these. */
     if(RegOpenKeyW(HKEY_LOCAL_MACHINE,
                    is_win9x() ? win9x_font_reg_key : winnt_font_reg_key,
-		   &hkey) == ERROR_SUCCESS) {
+                   &hkey) == ERROR_SUCCESS)
+    {
         LPWSTR data, valueW;
         RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-			 &valuelen, &datalen, NULL, NULL);
+                         &valuelen, &datalen, NULL, NULL);
 
-	valuelen++; /* returned value doesn't include room for '\0' */
-	valueW = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
-	data = HeapAlloc(GetProcessHeap(), 0, datalen * sizeof(WCHAR));
+        valuelen++; /* returned value doesn't include room for '\0' */
+        valueW = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
+        data = HeapAlloc(GetProcessHeap(), 0, datalen * sizeof(WCHAR));
         if (valueW && data)
         {
             dlen = datalen * sizeof(WCHAR);
             vlen = valuelen;
             while(RegEnumValueW(hkey, i++, valueW, &vlen, NULL, &type, (LPBYTE)data,
-                                &dlen) == ERROR_SUCCESS) {
+                                &dlen) == ERROR_SUCCESS)
+            {
                 if(data[0] && (data[1] == ':'))
                 {
                     if((unixname = wine_get_unix_file_name(data)))
@@ -2848,7 +2832,7 @@ BOOL WineEngInit(void)
         }
         HeapFree(GetProcessHeap(), 0, data);
         HeapFree(GetProcessHeap(), 0, valueW);
-	RegCloseKey(hkey);
+        RegCloseKey(hkey);
     }
 
     load_fontconfig_fonts();
@@ -2885,6 +2869,30 @@ BOOL WineEngInit(void)
         }
         RegCloseKey(hkey);
     }
+}
+
+/*************************************************************
+ *    WineEngInit
+ *
+ * Initialize FreeType library and create a list of available faces
+ */
+BOOL WineEngInit(void)
+{
+    HANDLE font_mutex;
+
+    /* update locale dependent font info in registry */
+    update_font_info();
+
+    if(!init_freetype()) return FALSE;
+
+    if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL)
+    {
+        ERR("Failed to create font mutex\n");
+        return FALSE;
+    }
+    WaitForSingleObject(font_mutex, INFINITE);
+
+    init_font_list();
 
     DumpFontList();
     LoadSubstList();

From: Huw Davies <huw at codeweavers.com>
Subject: [PATCH 3/5] gdi32: Cache the loaded font list properties.
Message-Id: <1317936368-4103-3-git-send-email-huw at codeweavers.com>
Date: Thu,  6 Oct 2011 16:26:06 -0500

---
 dlls/gdi32/freetype.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 122 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 62c0504..ecd01dc 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -472,6 +472,26 @@ typedef struct tagFontSubst {
     NameCs to;
 } FontSubst;
 
+/* Registry font cache key and value names */
+static const WCHAR wine_fonts_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
+                                       'F','o','n','t','s',0};
+static const WCHAR wine_fonts_cache_key[] = {'C','a','c','h','e',0};
+static const WCHAR english_name_value[] = {'E','n','g','l','i','s','h',' ','N','a','m','e',0};
+static const WCHAR face_index_value[] = {'I','n','d','e','x',0};
+static const WCHAR face_italic_value[] = {'I','t','a','l','i','c',0};
+static const WCHAR face_bold_value[] = {'B','o','l','d',0};
+static const WCHAR face_version_value[] = {'V','e','r','s','i','o','n',0};
+static const WCHAR face_external_value[] = {'E','x','t','e','r','n','a','l',0};
+static const WCHAR face_height_value[] = {'H','e','i','g','h','t',0};
+static const WCHAR face_width_value[] = {'W','i','d','t','h',0};
+static const WCHAR face_size_value[] = {'S','i','z','e',0};
+static const WCHAR face_x_ppem_value[] = {'X','p','p','e','m',0};
+static const WCHAR face_y_ppem_value[] = {'Y','p','p','e','m',0};
+static const WCHAR face_internal_leading_value[] = {'I','n','t','e','r','n','a','l',' ','L','e','a','d','i','n','g',0};
+static const WCHAR face_font_sig_value[] = {'F','o','n','t',' ','S','i','g','n','a','t','u','r','e',0};
+static const WCHAR face_full_name_value[] = {'F','u','l','l',' ','N','a','m','e','\0'};
+
+
 struct font_mapping
 {
     struct list entry;
@@ -1125,6 +1145,83 @@ static WCHAR *get_face_name(FT_Face ft_face, FT_UShort name_id, FT_UShort langua
     return ret;
 }
 
+static inline LONG reg_save_dword(HKEY hkey, const WCHAR *value, DWORD data)
+{
+    return RegSetValueExW(hkey, value, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD));
+}
+
+static LONG create_font_cache_key(HKEY *hkey, DWORD *disposition)
+{
+    LONG ret;
+    HKEY hkey_wine_fonts;
+
+    /* We don't want to create the fonts key as volatile, so open this first */
+    ret = RegCreateKeyExW(HKEY_CURRENT_USER, wine_fonts_key, 0, NULL, 0,
+                          KEY_ALL_ACCESS, NULL, &hkey_wine_fonts, NULL);
+    if(ret != ERROR_SUCCESS)
+    {
+        WARN("Can't create %s\n", debugstr_w(wine_fonts_key));
+        return ret;
+    }
+
+    ret = RegCreateKeyExW(hkey_wine_fonts, wine_fonts_cache_key, 0, NULL, REG_OPTION_VOLATILE,
+                          KEY_ALL_ACCESS, NULL, hkey, disposition);
+    RegCloseKey(hkey_wine_fonts);
+    return ret;
+}
+
+static void add_face_to_cache(Face *face)
+{
+    HKEY hkey_font_cache, hkey_family, hkey_face;
+    WCHAR *face_key_name;
+
+    create_font_cache_key(&hkey_font_cache, NULL);
+
+    RegCreateKeyExW(hkey_font_cache, face->family->FamilyName, 0,
+                    NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey_family, NULL);
+    if(face->family->EnglishName)
+        RegSetValueExW(hkey_family, english_name_value, 0, REG_SZ, (BYTE*)face->family->EnglishName,
+                       (strlenW(face->family->EnglishName) + 1) * sizeof(WCHAR));
+
+    if(face->scalable)
+        face_key_name = face->StyleName;
+    else
+    {
+        static const WCHAR fmtW[] = {'%','s','\\','%','d',0};
+        face_key_name = HeapAlloc(GetProcessHeap(), 0, (strlenW(face->StyleName) + 10) * sizeof(WCHAR));
+        sprintfW(face_key_name, fmtW, face->StyleName, face->size.y_ppem);
+    }
+    RegCreateKeyExW(hkey_family, face_key_name, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL,
+                    &hkey_face, NULL);
+    if(!face->scalable)
+        HeapFree(GetProcessHeap(), 0, face_key_name);
+
+    RegSetValueExA(hkey_face, "File Name", 0, REG_BINARY, (BYTE*)face->file, strlen(face->file) + 1);
+    if (face->FullName)
+        RegSetValueExW(hkey_face, face_full_name_value, 0, REG_SZ, (BYTE*)face->FullName,
+                       (strlenW(face->FullName) + 1) * sizeof(WCHAR));
+
+    reg_save_dword(hkey_face, face_index_value, face->face_index);
+    reg_save_dword(hkey_face, face_italic_value, (face->ntmFlags & NTM_ITALIC) != 0);
+    reg_save_dword(hkey_face, face_bold_value, (face->ntmFlags & NTM_BOLD) != 0);
+    reg_save_dword(hkey_face, face_version_value, face->font_version);
+    reg_save_dword(hkey_face, face_external_value, face->external);
+
+    RegSetValueExW(hkey_face, face_font_sig_value, 0, REG_BINARY, (BYTE*)&face->fs, sizeof(face->fs));
+
+    if(!face->scalable)
+    {
+        reg_save_dword(hkey_face, face_height_value, face->size.height);
+        reg_save_dword(hkey_face, face_width_value, face->size.width);
+        reg_save_dword(hkey_face, face_size_value, face->size.size);
+        reg_save_dword(hkey_face, face_x_ppem_value, face->size.x_ppem);
+        reg_save_dword(hkey_face, face_y_ppem_value, face->size.y_ppem);
+        reg_save_dword(hkey_face, face_internal_leading_value, face->size.internal_leading);
+    }
+    RegCloseKey(hkey_face);
+    RegCloseKey(hkey_family);
+    RegCloseKey(hkey_font_cache);
+}
 
 /*****************************************************************
  *  load_sfnt_table
@@ -1218,6 +1315,8 @@ static void AddFaceToFamily(Face *face, Family *family)
 
 #define ADDFONT_EXTERNAL_FONT 0x01
 #define ADDFONT_FORCE_BITMAP  0x02
+#define ADDFONT_ADD_TO_CACHE  0x04
+
 static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
 {
     FT_Face ft_face;
@@ -1537,6 +1636,9 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
                 }
             }
 
+            if(flags & ADDFONT_ADD_TO_CACHE)
+                add_face_to_cache(face);
+
             AddFaceToFamily(face, family);
 
         } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);
@@ -1806,7 +1908,11 @@ static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
 	if(S_ISDIR(statbuf.st_mode))
 	    ReadFontDir(path, external_fonts);
 	else
-	    AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0);
+        {
+            DWORD addfont_flags = ADDFONT_ADD_TO_CACHE;
+            if(external_fonts) addfont_flags |= ADDFONT_EXTERNAL_FONT;
+            AddFontFileToList(path, NULL, NULL, addfont_flags);
+        }
     }
     closedir(dir);
     return TRUE;
@@ -1874,7 +1980,7 @@ LOAD_FUNCPTR(FcPatternGetString);
         if(len < 4) continue;
         ext = &file[ len - 3 ];
         if(strcasecmp(ext, "pfa") && strcasecmp(ext, "pfb"))
-            AddFontFileToList(file, NULL, NULL,  ADDFONT_EXTERNAL_FONT);
+            AddFontFileToList(file, NULL, NULL, ADDFONT_EXTERNAL_FONT | ADDFONT_ADD_TO_CACHE);
     }
     pFcFontSetDestroy(fontset);
     pFcObjectSetDestroy(os);
@@ -1906,7 +2012,7 @@ static BOOL load_font_from_data_dir(LPCWSTR file)
         WideCharToMultiByte(CP_UNIXCP, 0, file, -1, unix_name + strlen(unix_name), len, NULL, NULL);
 
         EnterCriticalSection( &freetype_cs );
-        ret = AddFontFileToList(unix_name, NULL, NULL, ADDFONT_FORCE_BITMAP);
+        ret = AddFontFileToList(unix_name, NULL, NULL, ADDFONT_FORCE_BITMAP | ADDFONT_ADD_TO_CACHE);
         LeaveCriticalSection( &freetype_cs );
         HeapFree(GetProcessHeap(), 0, unix_name);
     }
@@ -1953,7 +2059,7 @@ static void load_system_fonts(void)
 
                 sprintfW(pathW, fmtW, windowsdir, data);
                 if((unixname = wine_get_unix_file_name(pathW))) {
-                    added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
+                    added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP | ADDFONT_ADD_TO_CACHE);
                     HeapFree(GetProcessHeap(), 0, unixname);
                 }
                 if (!added)
@@ -2125,8 +2231,11 @@ INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
 
         if((unixname = wine_get_unix_file_name(file)))
         {
+            DWORD addfont_flags = ADDFONT_FORCE_BITMAP;
+
+            if(!(flags & FR_PRIVATE)) addfont_flags |= ADDFONT_ADD_TO_CACHE;
             EnterCriticalSection( &freetype_cs );
-            ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
+            ret = AddFontFileToList(unixname, NULL, NULL, addfont_flags);
             LeaveCriticalSection( &freetype_cs );
             HeapFree(GetProcessHeap(), 0, unixname);
         }
@@ -2806,7 +2915,7 @@ static void init_font_list(void)
                 {
                     if((unixname = wine_get_unix_file_name(data)))
                     {
-                        AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
+                        AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP | ADDFONT_ADD_TO_CACHE);
                         HeapFree(GetProcessHeap(), 0, unixname);
                     }
                 }
@@ -2819,7 +2928,7 @@ static void init_font_list(void)
                     sprintfW(pathW, fmtW, windowsdir, data);
                     if((unixname = wine_get_unix_file_name(pathW)))
                     {
-                        added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
+                        added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP | ADDFONT_ADD_TO_CACHE);
                         HeapFree(GetProcessHeap(), 0, unixname);
                     }
                     if (!added)
@@ -2878,6 +2987,8 @@ static void init_font_list(void)
  */
 BOOL WineEngInit(void)
 {
+    HKEY hkey_font_cache;
+    DWORD disposition;
     HANDLE font_mutex;
 
     /* update locale dependent font info in registry */
@@ -2892,8 +3003,12 @@ BOOL WineEngInit(void)
     }
     WaitForSingleObject(font_mutex, INFINITE);
 
+    create_font_cache_key(&hkey_font_cache, &disposition);
+
     init_font_list();
 
+    RegCloseKey(hkey_font_cache);
+
     DumpFontList();
     LoadSubstList();
     DumpSubstList();

From: Huw Davies <huw at codeweavers.com>
Subject: [PATCH 4/5] gdi32: Load the font properties from the cache if it exists.
Message-Id: <1317936368-4103-4-git-send-email-huw at codeweavers.com>
Date: Thu,  6 Oct 2011 16:26:07 -0500

---
 dlls/gdi32/freetype.c |  183 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index ecd01dc..24935df 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1145,11 +1145,185 @@ static WCHAR *get_face_name(FT_Face ft_face, FT_UShort name_id, FT_UShort langua
     return ret;
 }
 
+static LONG reg_load_dword(HKEY hkey, const WCHAR *value, DWORD *data)
+{
+    DWORD type, needed;
+    LONG r = RegQueryValueExW(hkey, value, NULL, &type, NULL, &needed);
+    if(r != ERROR_SUCCESS) return r;
+    if(type != REG_DWORD || needed != sizeof(DWORD)) return ERROR_BAD_CONFIGURATION;
+    return RegQueryValueExW(hkey, value, NULL, &type, (BYTE*)data, &needed);
+}
+
 static inline LONG reg_save_dword(HKEY hkey, const WCHAR *value, DWORD data)
 {
     return RegSetValueExW(hkey, value, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD));
 }
 
+static void load_face(HKEY hkey_face, WCHAR *face_name, Family *family)
+{
+    DWORD needed;
+    DWORD num_strikes, max_strike_key_len;
+
+    /* If we have a File Name key then this is a real font, not just the parent
+       key of a bunch of non-scalable strikes */
+    if(RegQueryValueExA(hkey_face, "File Name", NULL, NULL, NULL, &needed) == ERROR_SUCCESS)
+    {
+        DWORD italic, bold;
+        Face *face;
+        face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
+        face->cached_enum_data = NULL;
+
+        face->file = HeapAlloc(GetProcessHeap(), 0, needed);
+        RegQueryValueExA(hkey_face, "File Name", NULL, NULL, (BYTE*)face->file, &needed);
+
+        face->StyleName = strdupW(face_name);
+        face->family = family;
+
+        if(RegQueryValueExW(hkey_face, face_full_name_value, NULL, NULL, NULL, &needed) == ERROR_SUCCESS)
+        {
+            WCHAR *fullName = HeapAlloc(GetProcessHeap(), 0, needed);
+            RegQueryValueExW(hkey_face, face_full_name_value, NULL, NULL, (BYTE*)fullName, &needed);
+            face->FullName = fullName;
+        }
+        else
+            face->FullName = NULL;
+
+        reg_load_dword(hkey_face, face_index_value, (DWORD*)&face->face_index);
+        reg_load_dword(hkey_face, face_italic_value, &italic);
+        reg_load_dword(hkey_face, face_bold_value, &bold);
+        reg_load_dword(hkey_face, face_version_value, (DWORD*)&face->font_version);
+        reg_load_dword(hkey_face, face_external_value, (DWORD*)&face->external);
+
+        needed = sizeof(face->fs);
+        RegQueryValueExW(hkey_face, face_font_sig_value, NULL, NULL, (BYTE*)&face->fs, &needed);
+        memset(&face->fs_links, 0, sizeof(face->fs_links));
+
+        if(reg_load_dword(hkey_face, face_height_value, (DWORD*)&face->size.height) != ERROR_SUCCESS)
+        {
+            face->scalable = TRUE;
+            memset(&face->size, 0, sizeof(face->size));
+        }
+        else
+        {
+            face->scalable = FALSE;
+            reg_load_dword(hkey_face, face_width_value, (DWORD*)&face->size.width);
+            reg_load_dword(hkey_face, face_size_value, (DWORD*)&face->size.size);
+            reg_load_dword(hkey_face, face_x_ppem_value, (DWORD*)&face->size.x_ppem);
+            reg_load_dword(hkey_face, face_y_ppem_value, (DWORD*)&face->size.y_ppem);
+            reg_load_dword(hkey_face, face_internal_leading_value, (DWORD*)&face->size.internal_leading);
+
+            TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
+                  face->size.height, face->size.width, face->size.size >> 6,
+                  face->size.x_ppem >> 6, face->size.y_ppem >> 6);
+        }
+
+        face->ntmFlags = 0;
+        if (italic) face->ntmFlags |= NTM_ITALIC;
+        if (bold) face->ntmFlags |= NTM_BOLD;
+        if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
+
+        TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
+              face->fs.fsCsb[0], face->fs.fsCsb[1],
+              face->fs.fsUsb[0], face->fs.fsUsb[1],
+              face->fs.fsUsb[2], face->fs.fsUsb[3]);
+
+        if(!italic && !bold)
+            list_add_head(&family->faces, &face->entry);
+        else
+            list_add_tail(&family->faces, &face->entry);
+
+        TRACE("Added font %s %s\n", debugstr_w(family->FamilyName), debugstr_w(face->StyleName));
+    }
+
+    /* do we have any bitmap strikes? */
+    RegQueryInfoKeyW(hkey_face, NULL, NULL, NULL, &num_strikes, &max_strike_key_len, NULL, NULL,
+                     NULL, NULL, NULL, NULL);
+    if(num_strikes != 0)
+    {
+        WCHAR strike_name[10];
+        DWORD strike_index = 0;
+
+        needed = sizeof(strike_name) / sizeof(WCHAR);
+        while(RegEnumKeyExW(hkey_face, strike_index++, strike_name, &needed,
+                            NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+        {
+            HKEY hkey_strike;
+            RegOpenKeyExW(hkey_face, strike_name, 0, KEY_ALL_ACCESS, &hkey_strike);
+            load_face(hkey_strike, face_name, family);
+            RegCloseKey(hkey_strike);
+            needed = sizeof(strike_name) / sizeof(WCHAR);
+        }
+    }
+}
+
+static void load_font_list_from_cache(HKEY hkey_font_cache)
+{
+    DWORD max_family_key_len, size;
+    WCHAR *family_name;
+    DWORD family_index = 0;
+    Family *family;
+    HKEY hkey_family;
+
+    RegQueryInfoKeyW(hkey_font_cache, NULL, NULL, NULL, NULL, &max_family_key_len, NULL, NULL,
+                     NULL, NULL, NULL, NULL);
+    family_name = HeapAlloc(GetProcessHeap(), 0, (max_family_key_len + 1) * sizeof(WCHAR));
+
+    size = max_family_key_len + 1;
+    while(RegEnumKeyExW(hkey_font_cache, family_index++, family_name, &size,
+                        NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+    {
+        WCHAR *english_family = NULL;
+        DWORD face_index = 0;
+        WCHAR *face_name;
+        DWORD max_face_key_len;
+
+        RegOpenKeyExW(hkey_font_cache, family_name, 0, KEY_ALL_ACCESS, &hkey_family);
+        TRACE("opened family key %s\n", debugstr_w(family_name));
+        if(RegQueryValueExW(hkey_family, english_name_value, NULL, NULL, NULL, &size) == ERROR_SUCCESS)
+        {
+            english_family = HeapAlloc(GetProcessHeap(), 0, size);
+            RegQueryValueExW(hkey_family, english_name_value, NULL, NULL, (BYTE*)english_family, &size);
+        }
+
+        family = HeapAlloc(GetProcessHeap(), 0, sizeof(*family));
+        family->FamilyName = strdupW(family_name);
+        family->EnglishName = english_family;
+        list_init(&family->faces);
+        list_add_tail(&font_list, &family->entry);
+
+        if(english_family)
+        {
+            FontSubst *subst = HeapAlloc(GetProcessHeap(), 0, sizeof(*subst));
+            subst->from.name = strdupW(english_family);
+            subst->from.charset = -1;
+            subst->to.name = strdupW(family_name);
+            subst->to.charset = -1;
+            add_font_subst(&font_subst_list, subst, 0);
+        }
+
+        RegQueryInfoKeyW(hkey_family, NULL, NULL, NULL, NULL, &max_face_key_len, NULL, NULL,
+                         NULL, NULL, NULL, NULL);
+
+        face_name = HeapAlloc(GetProcessHeap(), 0, (max_face_key_len + 1) * sizeof(WCHAR));
+        size = max_face_key_len + 1;
+        while(RegEnumKeyExW(hkey_family, face_index++, face_name, &size,
+                            NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+        {
+            HKEY hkey_face;
+
+            RegOpenKeyExW(hkey_family, face_name, 0, KEY_ALL_ACCESS, &hkey_face);
+            load_face(hkey_face, face_name, family);
+            RegCloseKey(hkey_face);
+            size = max_face_key_len + 1;
+        }
+        HeapFree(GetProcessHeap(), 0, face_name);
+        RegCloseKey(hkey_family);
+        size = max_family_key_len + 1;
+    }
+
+    HeapFree(GetProcessHeap(), 0, family_name);
+}
+
 static LONG create_font_cache_key(HKEY *hkey, DWORD *disposition)
 {
     LONG ret;
@@ -3005,7 +3179,10 @@ BOOL WineEngInit(void)
 
     create_font_cache_key(&hkey_font_cache, &disposition);
 
-    init_font_list();
+    if(disposition == REG_CREATED_NEW_KEY)
+        init_font_list();
+    else
+        load_font_list_from_cache(hkey_font_cache);
 
     RegCloseKey(hkey_font_cache);
 
@@ -3013,7 +3190,9 @@ BOOL WineEngInit(void)
     LoadSubstList();
     DumpSubstList();
     LoadReplaceList();
-    update_reg_entries();
+
+    if(disposition == REG_CREATED_NEW_KEY)
+        update_reg_entries();
 
     update_system_links();
     init_system_links();



More information about the wine-tests-results mailing list