[1/2] gdi32: Add GetTextMetrics test, make it pass under Wine. Take 3

Dmitry Timoshkov dmitry at codeweavers.com
Wed Mar 14 08:17:04 CDT 2007


Hello,

Alexandre asked me to add more test to see how Windows really calculates
tmA.tmFirstChar. I create a custom TTF font with fontforge and played
a bit with it, patching it in various ways. Alexandre is right, what
Windows returns in GetTextMetricsA/tmA.tmFirstChar is not that simple,
I left for now an old code which truncates tmW.tmFirstChar at 255.

This patch should resolve a problem reported in the bug 5783.

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

---
 dlls/gdi32/font.c        |   47 ++++++----
 dlls/gdi32/freetype.c    |   66 +++++++++++---
 dlls/gdi32/gdi_private.h |    4 +-
 dlls/gdi32/tests/font.c  |  219 +++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 299 insertions(+), 37 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 1b1d8b4..04b54cf 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1335,29 +1335,17 @@ BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
     return ret;
 }
 
-/***********************************************************************
- *           GetTextMetricsA    (GDI32.@)
- */
-BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
-{
-    TEXTMETRICW tm32;
-
-    if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
-    FONT_TextMetricWToA( &tm32, metrics );
-    return TRUE;
-}
-
-/***********************************************************************
- *           GetTextMetricsW    (GDI32.@)
- */
-BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
+static BOOL get_text_metrics( HDC hdc, TEXTMETRICW *tm, BOOL unicode )
 {
+    TEXTMETRICW tmW, *metrics;
     BOOL ret = FALSE;
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
 
+    metrics = unicode ? tm : &tmW;
+
     if (dc->gdiFont)
-        ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
+        ret = WineEngGetTextMetrics(dc->gdiFont, metrics, unicode);
     else if (dc->funcs->pGetTextMetrics)
         ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
 
@@ -1366,6 +1354,9 @@ BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
     /* device layer returns values in device units
      * therefore we have to convert them to logical */
 
+        metrics->tmDigitizedAspectX = GetDeviceCaps(hdc, LOGPIXELSX);
+        metrics->tmDigitizedAspectY = GetDeviceCaps(hdc, LOGPIXELSY);
+
 #define WDPTOLP(x) ((x<0)?					\
 		(-abs(INTERNAL_XDSTOWS(dc, (x)))):		\
 		(abs(INTERNAL_XDSTOWS(dc, (x)))))
@@ -1404,11 +1395,29 @@ BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
           metrics->tmAscent,
           metrics->tmDescent,
           metrics->tmHeight );
+
+        if (!unicode)
+            FONT_TextMetricWToA( metrics, (TEXTMETRICA *)tm );
     }
     GDI_ReleaseObj( hdc );
     return ret;
 }
 
+/***********************************************************************
+ *           GetTextMetricsW    (GDI32.@)
+ */
+BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
+{
+    return get_text_metrics( hdc, metrics, TRUE );
+}
+
+/***********************************************************************
+ *           GetTextMetricsA    (GDI32.@)
+ */
+BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
+{
+    return get_text_metrics( hdc, (TEXTMETRICW *)metrics, FALSE );
+}
 
 /***********************************************************************
  * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
@@ -1622,11 +1631,11 @@ UINT WINAPI GetOutlineTextMetricsW(
     if(!dc) return 0;
 
     if(dc->gdiFont) {
-        ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, output);
+        ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, output, TRUE);
         if(lpOTM && ret) {
             if(ret > cbData) {
                 output = HeapAlloc(GetProcessHeap(), 0, ret);
-                WineEngGetOutlineTextMetrics(dc->gdiFont, ret, output);
+                WineEngGetOutlineTextMetrics(dc->gdiFont, ret, output, TRUE);
             }
 
 #define WDPTOLP(x) ((x<0)?					\
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index db990fa..54ac771 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -3071,16 +3071,16 @@ static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
 
     memset(&pelf->elfLogFont, 0, sizeof(LOGFONTW));
 
-    size = WineEngGetOutlineTextMetrics(font, 0, NULL);
+    size = WineEngGetOutlineTextMetrics(font, 0, NULL, TRUE);
     if(size) {
         potm = HeapAlloc(GetProcessHeap(), 0, size);
-        WineEngGetOutlineTextMetrics(font, size, potm);
+        WineEngGetOutlineTextMetrics(font, size, potm, TRUE);
         ptm = (TEXTMETRICW*)&potm->otmTextMetrics;
     } else {
-        WineEngGetTextMetrics(font, &tm);
+        WineEngGetTextMetrics(font, &tm, TRUE);
         ptm = &tm;
     }
-        
+
     pntm->ntmTm.tmHeight = pelf->elfLogFont.lfHeight = ptm->tmHeight;
     pntm->ntmTm.tmAscent = ptm->tmAscent;
     pntm->ntmTm.tmDescent = ptm->tmDescent;
@@ -3337,7 +3337,7 @@ DWORD WineEngGetGlyphIndices(GdiFont *font, LPCWSTR lpstr, INT count,
         {
             if (!default_char)
             {
-                WineEngGetTextMetrics(font, &textm);
+                WineEngGetTextMetrics(font, &textm, TRUE);
                 default_char = textm.tmDefaultChar;
             }
             pgi[i] = default_char;
@@ -3873,20 +3873,41 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
     return TRUE;
 }
 
+static void fixup_ansi_metrics(GdiFont *font, TEXTMETRICW *tm)
+{
+    TT_OS2 *pOS2;
+
+    if (!FT_IS_SFNT(font->ft_face)) return;
+
+    /* FIXME: This is not exactly what Windows does */
+    tm->tmFirstChar = min(tm->tmFirstChar, 255);
+
+    /* pFT_Get_Sfnt_Table should always succeed at this point */
+    pOS2 = pFT_Get_Sfnt_Table(font->ft_face, ft_sfnt_os2);
+
+    if (font->charset == SYMBOL_CHARSET)
+        tm->tmLastChar = min(pOS2->usLastCharIndex - 0xf000, 255);
+    else
+        tm->tmLastChar = min(pOS2->usLastCharIndex, 255);
+}
+
 /*************************************************************
  * WineEngGetTextMetrics
  *
  */
-BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
+BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm, BOOL unicode)
 {
     if(!font->potm) {
-        if(!WineEngGetOutlineTextMetrics(font, 0, NULL))
+        if(!WineEngGetOutlineTextMetrics(font, 0, NULL, TRUE))
             if(!get_bitmap_text_metrics(font))
                 return FALSE;
     }
     if(!font->potm) return FALSE;
     memcpy(ptm, &font->potm->otmTextMetrics, sizeof(*ptm));
 
+    if (!unicode)
+        fixup_ansi_metrics(font, ptm);
+
     if (font->aveWidth) {
         ptm->tmAveCharWidth = font->aveWidth * font->font_desc.matrix.eM11;
     }
@@ -3899,7 +3920,7 @@ BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
  *
  */
 UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
-				  OUTLINETEXTMETRICW *potm)
+				  OUTLINETEXTMETRICW *potm, BOOL unicode)
 {
     FT_Face ft_face = font->ft_face;
     UINT needed, lenfam, lensty, ret;
@@ -3919,7 +3940,11 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
 
     if(font->potm) {
         if(cbSize >= font->potm->otmSize)
+        {
 	    memcpy(potm, font->potm, font->potm->otmSize);
+            if (!unicode)
+                fixup_ansi_metrics(font, &potm->otmTextMetrics);
+        }
 	return font->potm->otmSize;
     }
 
@@ -4022,10 +4047,21 @@ UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
     TM.tmOverhang = 0;
     TM.tmDigitizedAspectX = 300;
     TM.tmDigitizedAspectY = 300;
-    TM.tmFirstChar = pOS2->usFirstCharIndex;
-    TM.tmLastChar = pOS2->usLastCharIndex;
-    TM.tmDefaultChar = pOS2->usDefaultChar;
     TM.tmBreakChar = pOS2->usBreakChar ? pOS2->usBreakChar : ' ';
+    /* It appears that for fonts with SYMBOL_CHARSET Windows always sets
+     * symbol range to 0 - f0ff
+     */
+    if (font->charset == SYMBOL_CHARSET)
+    {
+        TM.tmFirstChar = 0;
+        TM.tmLastChar = 0xf0ff;
+    }
+    else
+    {
+        TM.tmFirstChar = pOS2->usFirstCharIndex;
+        TM.tmLastChar = pOS2->usLastCharIndex;
+    }
+    TM.tmDefaultChar = pOS2->usDefaultChar ? pOS2->usDefaultChar : 0x1f;
     TM.tmItalic = font->fake_italic ? 255 : ((ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0);
     TM.tmUnderlined = font->underline;
     TM.tmStruckOut = font->strikeout;
@@ -4306,7 +4342,7 @@ BOOL WineEngGetTextExtentExPoint(GdiFont *font, LPCWSTR wstr, INT count,
 	  max_ext, size);
 
     size->cx = 0;
-    WineEngGetTextMetrics(font, &tm);
+    WineEngGetTextMetrics(font, &tm, TRUE);
     size->cy = tm.tmHeight;
 
     for(idx = 0; idx < count; idx++) {
@@ -4343,7 +4379,7 @@ BOOL WineEngGetTextExtentPointI(GdiFont *font, const WORD *indices, INT count,
     TRACE("%p, %p, %d, %p\n", font, indices, count, size);
 
     size->cx = 0;
-    WineEngGetTextMetrics(font, &tm);
+    WineEngGetTextMetrics(font, &tm, TRUE);
     size->cy = tm.tmHeight;
 
     for(idx = 0; idx < count; idx++) {
@@ -4888,14 +4924,14 @@ DWORD WineEngGetGlyphOutline(GdiFont *font, UINT glyph, UINT format,
     return GDI_ERROR;
 }
 
-BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
+BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm, BOOL unicode)
 {
     ERR("called but we don't have FreeType\n");
     return FALSE;
 }
 
 UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
-				  OUTLINETEXTMETRICW *potm)
+				  OUTLINETEXTMETRICW *potm, BOOL unicode)
 {
     ERR("called but we don't have FreeType\n");
     return 0;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index e43ac30..47974c9 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -431,12 +431,12 @@ extern DWORD WineEngGetGlyphOutline(GdiFont*, UINT glyph, UINT format,
                                     const MAT2*);
 extern DWORD WineEngGetKerningPairs(GdiFont*, DWORD, KERNINGPAIR *);
 extern BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph);
-extern UINT WineEngGetOutlineTextMetrics(GdiFont*, UINT, LPOUTLINETEXTMETRICW);
+extern UINT WineEngGetOutlineTextMetrics(GdiFont*, UINT, LPOUTLINETEXTMETRICW, BOOL);
 extern UINT WineEngGetTextCharsetInfo(GdiFont *font, LPFONTSIGNATURE fs, DWORD flags);
 extern BOOL WineEngGetTextExtentExPoint(GdiFont*, LPCWSTR, INT, INT, LPINT, LPINT, LPSIZE);
 extern BOOL WineEngGetTextExtentPointI(GdiFont*, const WORD *, INT, LPSIZE);
 extern INT  WineEngGetTextFace(GdiFont*, INT, LPWSTR);
-extern BOOL WineEngGetTextMetrics(GdiFont*, LPTEXTMETRICW);
+extern BOOL WineEngGetTextMetrics(GdiFont*, LPTEXTMETRICW, BOOL);
 extern BOOL WineEngInit(void);
 extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID);
 
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index c695e13..18a2986 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -408,7 +408,7 @@ static void test_GdiGetCharDimensions(void)
 
     if (!pGdiGetCharDimensions)
     {
-        skip("GetFontUnicodeRanges not available on this platform\n");
+        skip("GdiGetCharDimensions not available on this platform\n");
         return;
     }
 
@@ -1149,6 +1149,7 @@ static void test_GetFontUnicodeRanges(void)
 
     size = pGetFontUnicodeRanges(hdc, gs);
     ok(size, "GetFontUnicodeRanges failed\n");
+    ok(gs->cRanges != 0, "GetFontUnicodeRanges returned empty ranges\n");
 #if 0
     for (i = 0; i < gs->cRanges; i++)
         trace("%03d wcLow %04x cGlyphs %u\n", i, gs->ranges[i].wcLow, gs->ranges[i].cGlyphs);
@@ -1397,6 +1398,221 @@ else
     ReleaseDC(0, hdc);
 }
 
+/* PANOSE is 10 bytes in size, need to pack the structure properly */
+#include "pshpack2.h"
+typedef struct
+{
+    USHORT version;
+    SHORT xAvgCharWidth;
+    USHORT usWeightClass;
+    USHORT usWidthClass;
+    SHORT fsType;
+    SHORT ySubscriptXSize;
+    SHORT ySubscriptYSize;
+    SHORT ySubscriptXOffset;
+    SHORT ySubscriptYOffset;
+    SHORT ySuperscriptXSize;
+    SHORT ySuperscriptYSize;
+    SHORT ySuperscriptXOffset;
+    SHORT ySuperscriptYOffset;
+    SHORT yStrikeoutSize;
+    SHORT yStrikeoutPosition;
+    SHORT sFamilyClass;
+    PANOSE panose;
+    ULONG ulUnicodeRange1;
+    ULONG ulUnicodeRange2;
+    ULONG ulUnicodeRange3;
+    ULONG ulUnicodeRange4;
+    CHAR achVendID[4];
+    USHORT fsSelection;
+    USHORT usFirstCharIndex;
+    USHORT usLastCharIndex;
+    /* According to the Apple spec, original version didn't have the below fields,
+     * version numbers were taked from the OpenType spec.
+     */
+    /* version 0 (TrueType 1.5) */
+    USHORT sTypoAscender;
+    USHORT sTypoDescender;
+    USHORT sTypoLineGap;
+    USHORT usWinAscent;
+    USHORT usWinDescent;
+    /* version 1 (TrueType 1.66) */
+    ULONG ulCodePageRange1;
+    ULONG ulCodePageRange2;
+    /* version 2 (OpenType 1.2) */
+    SHORT sxHeight;
+    SHORT sCapHeight;
+    USHORT usDefaultChar;
+    USHORT usBreakChar;
+    USHORT usMaxContext;
+} TT_OS2_V2;
+#include "poppack.h"
+
+#ifdef WORDS_BIGENDIAN
+#define GET_BE_WORD(x) (x)
+#else
+#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x)) 
+#endif
+
+#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
+                    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
+                    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
+#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
+
+static void test_text_metrics(const LOGFONTA *lf)
+{
+    HDC hdc;
+    HFONT hfont, hfont_old;
+    TEXTMETRICA tmA;
+    TEXTMETRICW tmW;
+    UINT first_unicode_char, last_unicode_char, default_char, break_char;
+    INT test_char;
+    TT_OS2_V2 tt_os2;
+    USHORT version;
+    LONG size, ret;
+    const char *font_name = lf->lfFaceName;
+
+    trace("Testing font metrics for %s, charset %d\n", font_name, lf->lfCharSet);
+
+    hdc = GetDC(0);
+
+    SetLastError(0xdeadbeef);
+    hfont = CreateFontIndirectA(lf);
+    ok(hfont != 0, "CreateFontIndirect error %u\n", GetLastError());
+
+    hfont_old = SelectObject(hdc, hfont);
+
+    size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
+    if (size == GDI_ERROR)
+    {
+        trace("OS/2 chunk was not found\n");
+        goto end_of_test;
+    }
+    if (size > sizeof(tt_os2))
+    {
+        trace("got too large OS/2 chunk of size %u\n", size);
+        size = sizeof(tt_os2);
+    }
+
+    memset(&tt_os2, 0, sizeof(tt_os2));
+    ret = GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size);
+    ok(ret == size, "GetFontData should return %u not %u\n", size, ret);
+
+    version = GET_BE_WORD(tt_os2.version);
+    trace("OS/2 chunk version %u, vendor %4.4s\n", version, (LPCSTR)&tt_os2.achVendID);
+
+    first_unicode_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
+    last_unicode_char = GET_BE_WORD(tt_os2.usLastCharIndex);
+    default_char = GET_BE_WORD(tt_os2.usDefaultChar);
+    break_char = GET_BE_WORD(tt_os2.usBreakChar);
+
+    trace("for %s first %x, last %x, default %x, break %x\n", font_name,
+           first_unicode_char, last_unicode_char, default_char, break_char);
+
+    SetLastError(0xdeadbeef);
+    ret = GetTextMetricsA(hdc, &tmA);
+    ok(ret, "GetTextMetricsA error %u\n", GetLastError());
+
+    trace("A: first %x, last %x, default %x, break %x\n",
+          tmA.tmFirstChar, tmA.tmLastChar, tmA.tmDefaultChar, tmA.tmBreakChar);
+
+    SetLastError(0xdeadbeef);
+    ret = GetTextMetricsW(hdc, &tmW);
+    ok(ret, "GetTextMetricsA error %u\n", GetLastError());
+
+    trace("W: first %x, last %x, default %x, break %x\n",
+          tmW.tmFirstChar, tmW.tmLastChar, tmW.tmDefaultChar, tmW.tmBreakChar);
+
+    if (lf->lfCharSet == SYMBOL_CHARSET)
+    {
+        test_char = min(last_unicode_char - 0xf000, 255);
+        ok(tmA.tmLastChar == test_char, "A: tmLastChar for %s %02x != %02x\n",
+           font_name, tmA.tmLastChar, test_char);
+
+        /* It appears that for fonts with SYMBOL_CHARSET Windows always sets
+         * symbol range to 0 - f0ff
+         */
+        ok(tmW.tmFirstChar == 0, "W: tmFirstChar for %s %02x != 0\n",
+           font_name, tmW.tmFirstChar);
+        ok(tmW.tmLastChar == 0xf0ff, "W: tmLastChar for %s %02x != 0xf0ff\n",
+           font_name, tmW.tmLastChar);
+
+        ok(tmA.tmDefaultChar == 0x1f, "A: tmDefaultChar for %s %02x != 0\n",
+           font_name, tmW.tmDefaultChar);
+        ok(tmA.tmBreakChar == 0x20, "A: tmBreakChar for %s %02x != 0xf0ff\n",
+           font_name, tmW.tmBreakChar);
+        ok(tmW.tmDefaultChar == 0x1f, "W: tmDefaultChar for %s %02x != 0\n",
+           font_name, tmW.tmDefaultChar);
+        ok(tmW.tmBreakChar == 0x20, "W: tmBreakChar for %s %02x != 0xf0ff\n",
+           font_name, tmW.tmBreakChar);
+    }
+    else
+    {
+        test_char = min(tmW.tmLastChar, 255);
+        ok(tmA.tmLastChar == test_char, "A: tmLastChar for %s %02x != %02x\n",
+           font_name, tmA.tmLastChar, test_char);
+
+        ok(tmW.tmFirstChar == first_unicode_char, "W: tmFirstChar for %s %02x != %02x\n",
+           font_name, tmW.tmFirstChar, first_unicode_char);
+        ok(tmW.tmLastChar == last_unicode_char, "W: tmLastChar for %s %02x != %02x\n",
+           font_name, tmW.tmLastChar, last_unicode_char);
+    }
+#if 0 /* FIXME: This doesn't appear to be what Windows does */
+    test_char = min(tmW.tmFirstChar - 1, 255);
+    ok(tmA.tmFirstChar == test_char, "A: tmFirstChar for %s %02x != %02x\n",
+       font_name, tmA.tmFirstChar, test_char);
+#endif
+    ret = GetDeviceCaps(hdc, LOGPIXELSX);
+    ok(tmW.tmDigitizedAspectX == ret, "tmDigitizedAspectX %u != %u\n",
+       tmW.tmDigitizedAspectX, ret);
+    ret = GetDeviceCaps(hdc, LOGPIXELSY);
+    ok(tmW.tmDigitizedAspectX == ret, "tmDigitizedAspectY %u != %u\n",
+       tmW.tmDigitizedAspectX, ret);
+
+end_of_test:
+    SelectObject(hdc, hfont_old);
+    DeleteObject(hfont);
+
+    ReleaseDC(0, hdc);
+}
+
+static INT CALLBACK enum_truetype_font_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+{
+    INT *enumed = (INT *)lParam;
+
+    if (type == TRUETYPE_FONTTYPE)
+    {
+        (*enumed)++;
+        test_text_metrics(lf);
+    }
+    return 1;
+}
+
+static void test_GetTextMetrics(void)
+{
+    LOGFONTA lf;
+    HDC hdc;
+    INT enumed;
+
+    SetLastError(0xdeadbeef);
+    GetTextMetricsW(0, NULL);
+    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        skip("Skipping GetTextMetrics test on a Win9x platform\n");
+        return;
+    }
+
+    hdc = GetDC(0);
+
+    memset(&lf, 0, sizeof(lf));
+    lf.lfCharSet = DEFAULT_CHARSET;
+    enumed = 0;
+    EnumFontFamiliesExA(hdc, &lf, enum_truetype_font_proc, (LPARAM)&enumed, 0);
+    trace("Tested metrics of %d truetype fonts\n", enumed);
+
+    ReleaseDC(0, hdc);
+}
+
 START_TEST(font)
 {
     init();
@@ -1427,4 +1643,5 @@ START_TEST(font)
     }
     else
         skip("Arial Black or Symbol/Wingdings is not installed\n");
+    test_GetTextMetrics();
 }
-- 
1.5.0.2






More information about the wine-patches mailing list