Huw Davies : gdi32: Separate face creation from face insertion.

Alexandre Julliard julliard at winehq.org
Tue Mar 27 12:48:06 CDT 2012


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Mar 27 11:48:47 2012 +0100

gdi32: Separate face creation from face insertion.

---

 dlls/gdi32/freetype.c |  156 +++++++++++++++++++++++++-----------------------
 1 files changed, 81 insertions(+), 75 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index d7accf0..8a077a9 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1448,7 +1448,7 @@ static inline int TestStyles(DWORD flags, DWORD styles)
     return (flags & styles) == styles;
 }
 
-static int StyleOrdering(Face *face)
+static inline int style_order(Face *face)
 {
     if (TestStyles(face->ntmFlags, NTM_BOLD | NTM_ITALIC))
         return 3;
@@ -1467,21 +1467,6 @@ static int StyleOrdering(Face *face)
     return 9999;
 }
 
-/* Add a style of face to a font family using an ordering of the list such
-   that regular fonts come before bold and italic, and single styles come
-   before compound styles.  */
-static void AddFaceToFamily(Face *face, Family *family)
-{
-    struct list *entry;
-
-    LIST_FOR_EACH( entry, &family->faces )
-    {
-        Face *ent = LIST_ENTRY(entry, Face, entry);
-        if (StyleOrdering(face) < StyleOrdering(ent)) break;
-    }
-    list_add_before( entry, &face->entry );
-}
-
 static WCHAR *prepend_at(WCHAR *family)
 {
     WCHAR *str;
@@ -1681,58 +1666,17 @@ static inline void free_face( Face *face )
 #define ADDFONT_FORCE_BITMAP  0x02
 #define ADDFONT_ADD_TO_CACHE  0x04
 
-static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr, DWORD font_data_size, FT_Long face_index, DWORD flags, BOOL vertical)
+static Face *create_face( FT_Face ft_face, FT_Long face_index, const char *file, void *font_data_ptr, DWORD font_data_size,
+                          DWORD flags, BOOL vertical )
 {
-    Family *family;
-    WCHAR *StyleW;
-    Face *face;
-    struct list *face_elem_ptr;
-    FONTSIGNATURE fs;
-    My_FT_Bitmap_Size *size = NULL;
-    FT_Fixed version;
+    Face *face = HeapAlloc( GetProcessHeap(), 0, sizeof(*face) );
+    My_FT_Bitmap_Size *size = (My_FT_Bitmap_Size *)ft_face->available_sizes;
 
-    if(!FT_IS_SCALABLE(ft_face))
-        size = (My_FT_Bitmap_Size *)ft_face->available_sizes;
-
-    family = get_family( ft_face, vertical );
-
-    StyleW = towstr(CP_ACP, ft_face->style_name);
-
-    get_fontsig( ft_face, &fs );
-
-    version = get_font_version( ft_face );
-    LIST_FOR_EACH(face_elem_ptr, &family->faces)
-    {
-        face = LIST_ENTRY(face_elem_ptr, Face, entry);
-        if(!strcmpiW(face->StyleName, StyleW) &&
-           (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) )))
-        {
-            TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
-                  debugstr_w(family->FamilyName), debugstr_w(StyleW),
-                  face->font_version, version);
-            if(version <= face->font_version)
-            {
-                TRACE("Original font is newer so skipping this one\n");
-                HeapFree(GetProcessHeap(), 0, StyleW);
-                return;
-            }
-            else
-            {
-                TRACE("Replacing original with this one\n");
-                list_remove(&face->entry);
-                free_face( face );
-                break;
-            }
-        }
-    }
-
-    face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
-    face->cached_enum_data = NULL;
-    face->StyleName = StyleW;
-    face->FullName = get_face_name(ft_face, TT_NAME_ID_FULL_NAME, TT_MS_LANGID_ENGLISH_UNITED_STATES);
+    face->StyleName = towstr( CP_ACP, ft_face->style_name );
+    face->FullName = get_face_name( ft_face, TT_NAME_ID_FULL_NAME, TT_MS_LANGID_ENGLISH_UNITED_STATES );
     if (file)
     {
-        face->file = strdupA(file);
+        face->file = strdupA( file );
         face->font_data_ptr = NULL;
         face->font_data_size = 0;
     }
@@ -1742,17 +1686,15 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr
         face->font_data_ptr = font_data_ptr;
         face->font_data_size = font_data_size;
     }
+
     face->face_index = face_index;
+    get_fontsig( ft_face, &face->fs );
     face->ntmFlags = get_ntm_flags( ft_face );
-    face->font_version = version;
-    face->family = family;
-    face->vertical = vertical;
-    face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
-    face->fs = fs;
+    face->font_version = get_font_version( ft_face );
 
-    if(FT_IS_SCALABLE(ft_face))
+    if (FT_IS_SCALABLE( ft_face ))
     {
-        memset(&face->size, 0, sizeof(face->size));
+        memset( &face->size, 0, sizeof(face->size) );
         face->scalable = TRUE;
     }
     else
@@ -1769,18 +1711,82 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr
         face->scalable = FALSE;
     }
 
+    face->vertical = vertical;
+    face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
+    face->family = NULL;
+    face->cached_enum_data = NULL;
+
     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(flags & ADDFONT_ADD_TO_CACHE)
-        add_face_to_cache(face);
+    return face;
+}
+
+static inline BOOL faces_equal( Face *f1, Face *f2 )
+{
+    if (strcmpiW( f1->StyleName, f2->StyleName )) return FALSE;
+    if (f1->scalable) return TRUE;
+    if (f2->size.y_ppem != f2->size.y_ppem) return FALSE;
+    return !memcmp( &f1->fs, &f2->fs, sizeof(f1->fs) );
+}
+
+static BOOL insert_face_in_family_list( Face *face, Family *family )
+{
+    Face *cursor;
+
+    LIST_FOR_EACH_ENTRY( cursor, &family->faces, Face, entry )
+    {
+        if (faces_equal( face, cursor ))
+        {
+            TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
+                  debugstr_w(family->FamilyName), debugstr_w(face->StyleName),
+                  cursor->font_version, face->font_version);
+
+            if (face->font_version <= cursor->font_version)
+            {
+                TRACE("Original font is newer so skipping this one\n");
+                return FALSE;
+            }
+            else
+            {
+                TRACE("Replacing original with this one\n");
+                list_add_before( &cursor->entry, &face->entry );
+                face->family = family;
+                list_remove( &cursor->entry);
+                free_face( cursor );
+                return TRUE;
+            }
+        }
+
+        if (style_order( face ) < style_order( cursor )) break;
+    }
+
+    list_add_before( &cursor->entry, &face->entry );
+    face->family = family;
+    return TRUE;
+}
+
+static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr, DWORD font_data_size,
+                          FT_Long face_index, DWORD flags, BOOL vertical)
+{
+    Face *face;
+    Family *family;
+
+    face = create_face( ft_face, face_index, file, font_data_ptr, font_data_size, flags, vertical );
+    family = get_family( ft_face, vertical );
+    if (!insert_face_in_family_list( face, family ))
+    {
+        free_face( face );
+        return;
+    }
 
-    AddFaceToFamily(face, family);
+    if (flags & ADDFONT_ADD_TO_CACHE)
+        add_face_to_cache( face );
 
     TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
-          debugstr_w(StyleW));
+          debugstr_w(face->StyleName));
 }
 
 static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, DWORD flags)




More information about the wine-cvs mailing list