[PATCH] gdi32: Don't enumerate fonts when OpenFontFace fails (try 2).

Qian Hong fracting at gmail.com
Fri Dec 7 10:49:43 CST 2012


On Fri, Dec 7, 2012 at 6:28 AM, Alexandre Julliard <julliard at winehq.org> wrote:
> ../../../tools/runtest -q -P wine -M gdiplus.dll -T ../../.. -p gdiplus_test.exe.so font.c && touch font.ok
> font.c:400: Test failed: Expected 0, got 3
> font.c:401: Test failed: got NULL font collection
> make[1]: *** [font.ok] Error 2

I can reproduce the failure with run gdiplus font test right after
gdi32 font test, however, if a `wineserver -k` is executed  between
the two test, then the gdiplus failure will disappear.

The attach patch should fix this problem.

This time I grepped
EnumFontFamilies/CreateScalableFontResource/AddFontResource in all
dlls and manually run similar tests with related dlls
(usp10/dwrite/oleaut32/comdlg32/gdiplus...), each test is executed
either right after gdi32/font test or independently, hopefully this
time such failure will not happen again.

This patch is here for fixing the side effect of
usp10/tests/usp10.c:test_ScriptGetFontProperties() fails due to this
side effect because the font file is removed but the wine_test font is
not removed from the font list since RemoveFontResource() is a stub in

However, the attached solution is not exactly match what Windows does:
On Windows, if the font file is deleted after
CreateScalableFontResource() and AddFontResource(), EnumFontFamilies
still enumerate the missing font until next reboot. Do we need to
follow what Windows does in this case?
I don't know if there is any real world app rely on this behavior, if
no I don't have a strong motivation for implementing it.

IMO the best solution is to correctly implement RemoveFontResource()
so Bug 8292 will be fixed, then we don't need to worry about the
broken test in usp10, which is the original reason for this patch.

Would you like me send this patch which is still an improvement, or
just leave the broken test there until RemoveFontResource is

Thanks for any suggestions.

Qian Hong

Sent from Ubuntu
-------------- next part --------------
From 1f4934e24fe6a9c56a206519e7214ccf8a4a66b8 Mon Sep 17 00:00:00 2001
From: Qian Hong <fracting at gmail.com>
Date: Thu, 6 Dec 2012 03:19:58 +0800
Subject: [PATCH] gdi32: Ignore fonts in enum_face_charsets if OpenFontFace
Reply-To: wine-devel at winehq.org
To: wine-patches at winehq.org

 dlls/gdi32/freetype.c |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 456a094..1ff8625 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -2992,7 +2992,7 @@ struct fontdir
 #include <poppack.h>
-static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
+static BOOL get_enum_structs(Face *face, LPENUMLOGFONTEXW pelf,
                            NEWTEXTMETRICEXW *pntm, LPDWORD ptype);
 static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
@@ -3012,7 +3012,11 @@ static BOOL get_fontdir( const char *unix_name, struct fontdir *fd )
     insert_face_in_family_list( face, family );
     pFT_Done_Face( ft_face );
-    GetEnumStructs( face, &elf, &ntm, &type );
+    if (!get_enum_structs( face, &elf, &ntm, &type ))
+    {
+        free_family( family );
+        return FALSE;
+    }
     free_family( family );
     if ((type & TRUETYPE_FONTTYPE) == 0) return FALSE;
@@ -5185,7 +5189,7 @@ static DWORD create_enum_charset_list(DWORD charset, struct enum_charset_list *l
     return n;
-static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
+static BOOL get_enum_structs(Face *face, LPENUMLOGFONTEXW pelf,
     GdiFont *font;
@@ -5197,7 +5201,7 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
         *pelf = face->cached_enum_data->elf;
         *pntm = face->cached_enum_data->ntm;
         *ptype = face->cached_enum_data->type;
-        return;
+        return TRUE;
     font = alloc_font();
@@ -5214,7 +5218,7 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
     if (!(font->ft_face = OpenFontFace(font, face, width, height)))
-        return;
+        return FALSE;
     font->name = strdupW(face->family->FamilyName);
@@ -5290,6 +5294,7 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
+    return TRUE;
 static BOOL family_matches(Family *family, const LOGFONTW *lf)
@@ -5324,7 +5329,7 @@ static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_cha
     DWORD type = 0;
     int i;
-    GetEnumStructs(face, &elf, &ntm, &type);
+    if (!get_enum_structs(face, &elf, &ntm, &type)) return TRUE;
     for(i = 0; i < list->total; i++) {
         if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
             elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;

More information about the wine-devel mailing list