From 2fdaa56693077a846b4844eb5611ec0fe21470bf Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Tue, 15 Jan 2008 16:02:29 +0800 Subject: [PATCH] gdi32: Add a test for undocumented EnumFontFamiliesEx(NULL), make it pass under Wine. --- dlls/gdi32/font.c | 62 ++++++++++++++++++++++++++-------------- dlls/gdi32/freetype.c | 8 ++++++ dlls/gdi32/tests/font.c | 12 ++++++++ dlls/winex11.drv/xfont.c | 9 ++++++ 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 66ae6d7e136..2789df52c49 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -692,7 +692,8 @@ static INT CALLBACK FONT_EnumInstance16( const LOGFONTW *plf, const TEXTMETRICW INT ret = 1; DC *dc; - if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || + if (!pfe->lpLogFontParam || + pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || pfe->lpLogFontParam->lfCharSet == plf->lfCharSet ) { WORD args[7]; @@ -740,7 +741,8 @@ static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *p DC *dc; /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */ - if((pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || + if ((!pfe->lpLogFontParam || + pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) && (!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) ) { @@ -785,11 +787,17 @@ INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf, DC* dc = DC_GetDCPtr( HDC_32(hDC) ); NEWTEXTMETRICEX16 tm16; ENUMLOGFONTEX16 lf16; - LOGFONTW lfW; + LOGFONTW lfW, *plfW; BOOL enum_gdi_fonts; if (!dc) return 0; - FONT_LogFont16ToW(plf, &lfW); + + if (plf) + { + FONT_LogFont16ToW(plf, &lfW); + plfW = &lfW; + } + else plfW = NULL; fe16.hdc = HDC_32(hDC); fe16.dc = dc; @@ -812,10 +820,10 @@ INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf, } if (enum_gdi_fonts) - ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 ); + ret = WineEngEnumFonts( plfW, FONT_EnumInstance16, (LPARAM)&fe16 ); fe16.dwFlags &= ~ENUM_CALLED; if (ret && dc->funcs->pEnumDeviceFonts) { - ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 ); + ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plfW, FONT_EnumInstance16, (LPARAM)&fe16 ); if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */ ret = ret2; } @@ -888,10 +896,16 @@ INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf, FONTENUMPROCA efproc, LPARAM lParam, DWORD dwFlags) { - LOGFONTW lfW; - FONT_LogFontAToW( plf, &lfW ); + LOGFONTW lfW, *plfW; - return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0); + if (plf) + { + FONT_LogFontAToW( plf, &lfW ); + plfW = &lfW; + } + else plfW = NULL; + + return FONT_EnumFontFamiliesEx( hDC, plfW, (FONTENUMPROCW)efproc, lParam, 0); } /*********************************************************************** @@ -900,17 +914,19 @@ INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf, INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily, FONTENUMPROC16 efproc, LPARAM lpData ) { - LOGFONT16 lf; + LOGFONT16 lf, *plf; - lf.lfCharSet = DEFAULT_CHARSET; if (lpFamily) { if (!*lpFamily) return 1; lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE ); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = 0; + plf = &lf; } - else lf.lfFaceName[0] = '\0'; + else plf = NULL; - return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 ); + return EnumFontFamiliesEx16( hDC, plf, efproc, lpData, 0 ); } /*********************************************************************** @@ -919,17 +935,19 @@ INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily, INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily, FONTENUMPROCA efproc, LPARAM lpData ) { - LOGFONTA lf; + LOGFONTA lf, *plf; - lf.lfCharSet = DEFAULT_CHARSET; if (lpFamily) { if (!*lpFamily) return 1; lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE ); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = 0; + plf = &lf; } - else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0'; + else plf = NULL; - return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 ); + return EnumFontFamiliesExA( hDC, plf, efproc, lpData, 0 ); } /*********************************************************************** @@ -938,17 +956,19 @@ INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily, INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily, FONTENUMPROCW efproc, LPARAM lpData ) { - LOGFONTW lf; + LOGFONTW lf, *plf; - lf.lfCharSet = DEFAULT_CHARSET; if (lpFamily) { if (!*lpFamily) return 1; lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE ); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = 0; + plf = &lf; } - else lf.lfFaceName[0] = 0; + else plf = NULL; - return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 ); + return EnumFontFamiliesExW( hDC, plf, efproc, lpData, 0 ); } /*********************************************************************** diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 562c32994ca..7689cf96855 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -3371,6 +3371,14 @@ DWORD WineEngEnumFonts(LPLOGFONTW plf, FONTENUMPROCW proc, LPARAM lparam) LOGFONTW lf; int i; + if (!plf) + { + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfPitchAndFamily = 0; + lf.lfFaceName[0] = 0; + plf = &lf; + } + TRACE("facename = %s charset %d\n", debugstr_w(plf->lfFaceName), plf->lfCharSet); if(plf->lfFaceName[0]) { diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 6138731e0b5..ee577c67a2e 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1287,6 +1287,18 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset) ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n"); ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n"); ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n"); + + efd.total = 0; + SetLastError(0xdeadbeef); + ret = EnumFontFamiliesEx(hdc, NULL, arial_enum_proc, (LPARAM)&efd, 0); + ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError()); + get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset); + trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n", + ansi_charset, symbol_charset, russian_charset); + ok(efd.total > 0, "no fonts enumerated: NULL\n"); + ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n"); + ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n"); + ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n"); } efd.total = 0; diff --git a/dlls/winex11.drv/xfont.c b/dlls/winex11.drv/xfont.c index 3298818153f..a55e77dc0bd 100644 --- a/dlls/winex11.drv/xfont.c +++ b/dlls/winex11.drv/xfont.c @@ -3305,10 +3305,19 @@ BOOL X11DRV_EnumDeviceFonts( X11DRV_PDEVICE *physDev, LPLOGFONTW plf, NEWTEXTMETRICEXW tm; fontResource* pfr = fontList; BOOL b, bRet = 0; + LOGFONTW lfW; /* don't enumerate x11 fonts if we're using client side fonts */ if (physDev->has_gdi_font) return FALSE; + if (!plf) + { + lfW.lfCharSet = DEFAULT_CHARSET; + lfW.lfPitchAndFamily = 0; + lfW.lfFaceName[0] = 0; + plf = &lfW; + } + if( plf->lfFaceName[0] ) { char facename[LF_FACESIZE+1];