Huw Davies : gdi32: Load the font properties from the cache if it exists.

Alexandre Julliard julliard at winehq.org
Thu Oct 6 17:24:31 CDT 2011


Module: wine
Branch: master
Commit: 17e72c816b9cbc17aeaae1c2ecf2ba230083817d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=17e72c816b9cbc17aeaae1c2ecf2ba230083817d

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Oct  6 16:26:07 2011 -0500

gdi32: Load the font properties from the cache if it exists.

---

 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-cvs mailing list