gdi32: Add font faces to families in a specific order.

Dan Hipschman dsh at linux.ucla.edu
Tue Apr 29 15:10:01 CDT 2008


This makes sure faces are added to family lists such that regular comes
before bold / italic, etc.  Without this the EnumFont lists may contain
stylized faces but not the regular face.  E.g., on my system it would
show Arial Bold, but not Arial, and it is not unheard-of to assume Arial
will always be enumerated.

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

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 82150d3..9a7d07a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1116,6 +1116,44 @@ static FT_Error load_sfnt_table(FT_Face ft_face, FT_ULong table, FT_Long offset,
     return err;
 }
 
+static int StyleOrdering(Face *face)
+{
+    switch (face->ntmFlags & 0xff)
+    {
+    case NTM_REGULAR: return 0;
+    case NTM_BOLD: return 1;
+    case NTM_ITALIC: return 2;
+    case NTM_BOLD | NTM_ITALIC: return 3;
+    }
+    return 4;
+}
+
+/* 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)
+{
+    if (list_empty(&family->faces))
+    {
+        list_add_head(&family->faces, &face->entry);
+    }
+    else
+    {
+        struct list *next = list_head(&family->faces);
+        while (next)
+        {
+            Face *ent = LIST_ENTRY(next, Face, entry);
+            if (StyleOrdering(face) < StyleOrdering(ent))
+            {
+                list_add_before(next, &face->entry);
+                break;
+            }
+            next = list_next(&family->faces, next);
+        }
+        if (!next)
+            list_add_tail(&family->faces, &face->entry);
+    }
+}
 
 #define ADDFONT_EXTERNAL_FONT 0x01
 #define ADDFONT_FORCE_BITMAP  0x02
@@ -1363,7 +1401,6 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
             }
             face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
             face->cached_enum_data = NULL;
-            list_add_tail(&family->faces, &face->entry);
             face->StyleName = StyleW;
             if (file)
             {
@@ -1438,6 +1475,9 @@ static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_
 
             if (!(face->fs.fsCsb[0] & FS_SYMBOL))
                 have_installed_roman_font = TRUE;
+
+            AddFaceToFamily(face, family);
+
         } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);
 
 	num_faces = ft_face->num_faces;



More information about the wine-patches mailing list