[5/5] gdi32: Add each external font to registry only once.

Kusanagi Kouichi slash at ac.auone-net.jp
Sun Apr 22 05:56:36 CDT 2012


Signed-off-by: Kusanagi Kouichi <slash at ac.auone-net.jp>
---
 dlls/gdi32/freetype.c |   99 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 60 insertions(+), 39 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 57188aa0..b17919a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -262,6 +262,7 @@ typedef struct tagFont
     char *file;
     void *data_ptr;
     DWORD data_size;
+    BOOL external; /* TRUE if we should manually add this font to the registry */
     struct list faces;
 } Font;
 
@@ -278,7 +279,6 @@ typedef struct tagFace {
     BOOL scalable;
     BOOL vertical;
     Bitmap_Size size;     /* set if face is a bitmap */
-    BOOL external; /* TRUE if we should manually add this font to the registry */
     struct tagFamily *family;
     /* Cached data for Enum */
     struct enum_data *cached_enum_data;
@@ -1751,7 +1751,7 @@ static inline void get_fontsig( FT_Face ft_face, FONTSIGNATURE *fs )
 #define ADDFONT_ADD_TO_CACHE  0x04
 
 static Face *create_face( FT_Face ft_face, FT_Long face_index, const Font *font,
-                          DWORD flags, BOOL vertical )
+                          BOOL vertical )
 {
     Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
     My_FT_Bitmap_Size *size = (My_FT_Bitmap_Size *)ft_face->available_sizes;
@@ -1786,7 +1786,6 @@ static Face *create_face( FT_Face ft_face, FT_Long face_index, const Font *font,
     }
 
     face->vertical = vertical;
-    face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
     face->family = NULL;
     face->cached_enum_data = NULL;
 
@@ -1804,7 +1803,7 @@ static void AddFaceToList(FT_Face ft_face, Font *font,
     Face *face;
     Family *family;
 
-    face = create_face( ft_face, face_index, font, flags, vertical );
+    face = create_face( ft_face, face_index, font, vertical );
     list_add_tail(&font->faces, &face->font_entry);
     family = get_family( ft_face, vertical );
     if (!insert_face_in_family_list( face, family ))
@@ -1951,6 +1950,7 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
         font->data_ptr = font_data_ptr;
         font->data_size = font_data_size;
     }
+    font->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
     list_init(&font->faces);
 
     do {
@@ -2686,10 +2686,7 @@ static void update_reg_entries(void)
 {
     HKEY winnt_key = 0, win9x_key = 0, external_key = 0;
     LPWSTR valueW;
-    DWORD len, len_fam;
-    Family *family;
-    Face *face;
-    struct list *family_elem_ptr, *face_elem_ptr;
+    const struct list *font_elem_ptr;
     WCHAR *file;
     static const WCHAR TrueType[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'};
     static const WCHAR spaceW[] = {' ', '\0'};
@@ -2715,44 +2712,68 @@ static void update_reg_entries(void)
 
     /* enumerate the fonts and add external ones to the two keys */
 
-    LIST_FOR_EACH(family_elem_ptr, &family_list) {
-        family = LIST_ENTRY(family_elem_ptr, Family, entry); 
-        len_fam = strlenW(family->FamilyName) + sizeof(TrueType) / sizeof(WCHAR) + 1;
-        LIST_FOR_EACH(face_elem_ptr, &family->faces) {
-            face = LIST_ENTRY(face_elem_ptr, Face, entry);
-            if(!face->external) continue;
-            len = len_fam;
+    LIST_FOR_EACH(font_elem_ptr, &font_list)
+    {
+        const Font * const font = LIST_ENTRY(font_elem_ptr, Font, entry); 
+        DWORD len;
+        const struct list *face_elem_ptr;
+
+        if (!font->external)
+            continue;
+
+        valueW = HeapAlloc(GetProcessHeap(), 0, sizeof TrueType);
+        if (valueW == NULL)
+            continue;
+
+        valueW[0] = '\0';
+        len = sizeof TrueType / sizeof TrueType[0];
+        LIST_FOR_EACH(face_elem_ptr, &font->faces)
+        {
+            const Face * const face = LIST_ENTRY(face_elem_ptr, Face, font_entry);
+            static const WCHAR and[] = {' ', '&', ' ', '\0'};
+            LPWSTR tmp;
+
+            if (face->vertical)
+                continue;
+
+            len += strlenW(face->family->FamilyName) + 3;
             if (!(face->ntmFlags & NTM_REGULAR))
-                len = len_fam + strlenW(face->StyleName) + 1;
-            valueW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-            strcpyW(valueW, family->FamilyName);
-            if(len != len_fam) {
+                len += strlenW(face->StyleName) + 1;
+            tmp = HeapReAlloc(GetProcessHeap(), 0, valueW, len * sizeof(WCHAR));
+            if (tmp == NULL)
+                goto next_font;
+            valueW = tmp;
+            strcatW(valueW, face->family->FamilyName);
+            if (!(face->ntmFlags & NTM_REGULAR))
+            {
                 strcatW(valueW, spaceW);
                 strcatW(valueW, face->StyleName);
             }
-            strcatW(valueW, TrueType);
+            strcatW(valueW, and);
+        }
+        strcpyW(valueW + len - sizeof TrueType / sizeof TrueType[0] - 3, TrueType);
 
-            file = wine_get_dos_file_name(face->font->file);
-            if(file)
-                len = strlenW(file) + 1;
+        file = wine_get_dos_file_name(font->file);
+        if(file)
+            len = strlenW(file) + 1;
+        else
+        {
+            if((path = strrchr(font->file, '/')) == NULL)
+                path = font->file;
             else
-            {
-                if((path = strrchr(face->font->file, '/')) == NULL)
-                    path = face->font->file;
-                else
-                    path++;
-                len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
-
-                file = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-                MultiByteToWideChar(CP_ACP, 0, path, -1, file, len);
-            }
-            RegSetValueExW(winnt_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
-            RegSetValueExW(win9x_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
-            RegSetValueExW(external_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
+                path++;
+            len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
 
-            HeapFree(GetProcessHeap(), 0, file);
-            HeapFree(GetProcessHeap(), 0, valueW);
+            file = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, path, -1, file, len);
         }
+        RegSetValueExW(winnt_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
+        RegSetValueExW(win9x_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
+        RegSetValueExW(external_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
+
+        HeapFree(GetProcessHeap(), 0, file);
+    next_font:
+        HeapFree(GetProcessHeap(), 0, valueW);
     }
  end:
     if(external_key) RegCloseKey(external_key);
@@ -3046,7 +3067,7 @@ static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
 
     if (!ft_face) return FALSE;
     font.file = (char *)unix_name;
-    face = create_face( ft_face, 0, &font, 0, FALSE );
+    face = create_face( ft_face, 0, &font, FALSE );
     get_family_names( ft_face, &name, &english_name, FALSE );
     family = create_family( name, english_name );
     insert_face_in_family_list( face, family );
-- 
1.7.10




More information about the wine-patches mailing list