gdi32: Add a EnumFontFamilies test, make it pass under Wine. Try 2

Dmitry Timoshkov dmitry at codeweavers.com
Fri Mar 2 01:01:59 CST 2007


Hello,

this patch should fix the problem reported in the bug #7571.

This version of the patch adds a test for the case of enumerating "Symbol"-like
fonts (pointed out by Huw), and makes it pass under Wine as well.

Changelog:
    gdi32: Add a EnumFontFamilies test, make it pass under Wine.

---
 dlls/gdi32/font.c       |   18 ++++++-
 dlls/gdi32/tests/font.c |  111 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index f237612..fac0312 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -38,6 +38,9 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(font);
 
+/* magic charset value to enumerate only single font charset */
+#define FONT_CHARSET (BYTE)0x0f
+
   /* Device -> World size conversion */
 
 /* Performs a device to world transformation on the specified width (which
@@ -714,8 +717,14 @@ static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *p
     INT ret = 1;
     DC *dc;
 
+#if 0
+    TRACE("asked for %s charset %u, got %s charset %u\n",
+          debugstr_w(pfe->lpLogFontParam->lfFaceName), pfe->lpLogFontParam->lfCharSet,
+          debugstr_w(plf->lfFaceName), plf->lfCharSet);
+#endif
     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
     if((pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
+        pfe->lpLogFontParam->lfCharSet == FONT_CHARSET ||
         pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) &&
        (!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) )
     {
@@ -735,6 +744,9 @@ static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *p
 
         ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
 
+        /* FONT_CHARSET means to enumerate only single font charset */
+        if (pfe->lpLogFontParam->lfCharSet == FONT_CHARSET) ret = 0;
+
         /* get the lock again and make sure the DC is still valid */
         dc = DC_GetDCPtr( pfe->hdc );
         if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
@@ -876,7 +888,7 @@ INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
 {
     LOGFONT16	lf;
 
-    lf.lfCharSet = DEFAULT_CHARSET;
+    lf.lfCharSet = FONT_CHARSET;
     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
     else lf.lfFaceName[0] = '\0';
 
@@ -891,7 +903,7 @@ INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
 {
     LOGFONTA	lf;
 
-    lf.lfCharSet = DEFAULT_CHARSET;
+    lf.lfCharSet = FONT_CHARSET;
     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
 
@@ -906,7 +918,7 @@ INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
 {
     LOGFONTW  lf;
 
-    lf.lfCharSet = DEFAULT_CHARSET;
+    lf.lfCharSet = FONT_CHARSET;
     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
     else lf.lfFaceName[0] = 0;
 
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 0a9f8d3..c9bce2b 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1088,6 +1088,112 @@ static void test_font_charset(void)
         skip("Symbol or Wingdings is not installed\n");
 }
 
+#define MAX_ENUM_FONTS 64
+
+struct enum_font_data
+{
+    int total;
+    LOGFONT lf[MAX_ENUM_FONTS];
+};
+
+static INT CALLBACK arial_enum_proc(const LOGFONT *lf, const TEXTMETRIC *tm, DWORD type, LPARAM lParam)
+{
+    struct enum_font_data *efd = (struct enum_font_data *)lParam;
+#if 0
+    trace("enumed font \"%s\", charset %d, weight %d, italic %d\n",
+          lf->lfFaceName, lf->lfCharSet, lf->lfWeight, lf->lfItalic);
+#endif
+    if (efd->total < MAX_ENUM_FONTS)
+    {
+        efd->lf[efd->total++] = *lf;
+        return 1;
+    }
+    return 0;
+}
+
+static void test_EnumFontFamilies(const char *font_name, INT font_charset)
+{
+    struct enum_font_data efd;
+    LOGFONT lf;
+    HDC hdc;
+    int i, got_not_ansi_charset;
+
+    trace("Testing font %s, charset %d\n", font_name, font_charset);
+
+    if (!is_font_installed(font_name))
+    {
+        skip("%s is not installed\n", font_name);
+        return;
+    }
+
+    hdc = GetDC(0);
+
+    efd.total = 0;
+    EnumFontFamilies(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
+    ok(efd.total > 0, "no fonts enumerated: %s\n", font_name);
+    for (i = 0; i < efd.total; i++)
+    {
+        ok(efd.lf[i].lfCharSet == font_charset, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
+        ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+           font_name, efd.lf[i].lfFaceName);
+    }
+
+    memset(&lf, 0, sizeof(lf));
+    lf.lfCharSet = ANSI_CHARSET;
+    lstrcpy(lf.lfFaceName, font_name);
+    efd.total = 0;
+    EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    if (font_charset == SYMBOL_CHARSET)
+        ok(efd.total == 0, "no fonts should be enumerated: %s ANSI_CHARSET\n", font_name);
+    else
+    {
+        ok(efd.total > 0, "no fonts enumerated: %s ANSI_CHARSET\n", font_name);
+        for (i = 0; i < efd.total; i++)
+        {
+            ok(efd.lf[i].lfCharSet == ANSI_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
+            ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+               font_name, efd.lf[i].lfFaceName);
+        }
+    }
+
+    /* DEFAULT_CHARSET should enumerate all available charsets */
+    memset(&lf, 0, sizeof(lf));
+    lf.lfCharSet = DEFAULT_CHARSET;
+    lstrcpy(lf.lfFaceName, font_name);
+    efd.total = 0;
+    EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    ok(efd.total > 0, "no fonts enumerated: %s DEFAULT_CHARSET\n", font_name);
+    got_not_ansi_charset = 0;
+    for (i = 0; i < efd.total; i++)
+    {
+        if (efd.lf[i].lfCharSet != ANSI_CHARSET)
+            got_not_ansi_charset++;
+        ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+           font_name, efd.lf[i].lfFaceName);
+    }
+    ok(got_not_ansi_charset != 0, "DEFAULT_CHARSET should enumerate all available charsets\n");
+
+    memset(&lf, 0, sizeof(lf));
+    lf.lfCharSet = SYMBOL_CHARSET;
+    lstrcpy(lf.lfFaceName, font_name);
+    efd.total = 0;
+    EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    if (font_charset != SYMBOL_CHARSET)
+        ok(efd.total == 0, "no fonts should be enumerated: %s SYMBOL_CHARSET\n", font_name);
+    else
+    {
+        ok(efd.total > 0, "no fonts enumerated: %s SYMBOL_CHARSET\n", font_name);
+        for (i = 0; i < efd.total; i++)
+        {
+            ok(efd.lf[i].lfCharSet == SYMBOL_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
+            ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+               font_name, efd.lf[i].lfFaceName);
+        }
+    }
+
+    ReleaseDC(0, hdc);
+}
+
 START_TEST(font)
 {
     test_logfont();
@@ -1101,4 +1207,9 @@ START_TEST(font)
     test_GetOutlineTextMetrics();
     test_SetTextJustification();
     test_font_charset();
+    /* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
+     * I'd like to avoid them in this test.
+     */
+    test_EnumFontFamilies("Arial Black", ANSI_CHARSET);
+    test_EnumFontFamilies("Symbol", SYMBOL_CHARSET);
 }
-- 
1.5.0






More information about the wine-patches mailing list