gdi32: Add font faces to families in a specific order. [take 2]

Dan Hipschman dsh at linux.ucla.edu
Wed Apr 30 13:51:00 CDT 2008


This improvement simplifies the list manipulation code and doesn't make
assumptions about the format of ntmFlags.

Again, this fixes problems with apps that assume, e.g., Arial, will be
in the enumerated font list (whereas on my system I have Arial, but only
Arial Bold shows up in the list because it's the first to be added).

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

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 82150d3..3f597de 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1116,6 +1116,49 @@ static FT_Error load_sfnt_table(FT_Face ft_face, FT_ULong table, FT_Long offset,
     return err;
 }
 
+static inline int TestStyles(DWORD flags, DWORD styles)
+{
+    return (flags & styles) == styles;
+}
+
+static int StyleOrdering(Face *face)
+{
+    if (TestStyles(face->ntmFlags, NTM_BOLD | NTM_ITALIC))
+        return 3;
+    if (TestStyles(face->ntmFlags, NTM_ITALIC))
+        return 2;
+    if (TestStyles(face->ntmFlags, NTM_BOLD))
+        return 1;
+    if (TestStyles(face->ntmFlags, NTM_REGULAR))
+        return 0;
+
+    WARN("Don't know how to order font %s %s with flags 0x%08x\n",
+         debugstr_w(face->family->FamilyName),
+         debugstr_w(face->StyleName),
+         face->ntmFlags);
+
+    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 *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 +1406,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 +1480,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