diff --git a/dlls/gdi/win16drv/font.c b/dlls/gdi/win16drv/font.c index 73fc73c472..6af457a17e 100644 --- a/dlls/gdi/win16drv/font.c +++ b/dlls/gdi/win16drv/font.c @@ -194,22 +194,16 @@ BOOL WIN16DRV_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar, * WIN16DRV_EnumDeviceFonts */ -BOOL WIN16DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, - DEVICEFONTENUMPROC proc, LPARAM lp ) +BOOL WIN16DRV_EnumDeviceFonts( PHYSDEV dev, LPLOGFONTW plf, + DEVICEFONTENUMPROC proc, LPARAM lp ) { - WIN16DRV_PDEVICE *physDev; + WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev; WORD wRet; WEPFC wepfc; - DC *dc; char *FaceNameA = NULL; /* EnumDFontCallback is GDI.158 */ FARPROC16 pfnCallback = GetProcAddress16( GetModuleHandle16("GDI"), (LPCSTR)158 ); - if (!(dc = DC_GetDCPtr( hdc ))) return 0; - physDev = (WIN16DRV_PDEVICE *)dc->physDev; - /* FIXME!! */ - GDI_ReleaseObj( hdc ); - wepfc.proc = proc; wepfc.lp = lp; diff --git a/dlls/gdi/win16drv/win16drv.h b/dlls/gdi/win16drv/win16drv.h index dbf94394ca..0b56d5f5c7 100644 --- a/dlls/gdi/win16drv/win16drv.h +++ b/dlls/gdi/win16drv/win16drv.h @@ -279,7 +279,8 @@ extern HPEN WIN16DRV_SelectPen( PHYSDEV dev, HPEN handle ); extern BOOL WIN16DRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height, DWORD rop ); extern BOOL WIN16DRV_Ellipse(PHYSDEV dev, INT left, INT top, INT right, INT bottom); -extern BOOL WIN16DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, DEVICEFONTENUMPROC proc, LPARAM lp ); +extern BOOL WIN16DRV_EnumDeviceFonts( PHYSDEV dev, LPLOGFONTW plf, + DEVICEFONTENUMPROC proc, LPARAM lp ); extern INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput, diff --git a/dlls/wineps/font.c b/dlls/wineps/font.c index 2c09aeb45d..84b7598d7d 100644 --- a/dlls/wineps/font.c +++ b/dlls/wineps/font.c @@ -386,8 +386,8 @@ BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev ) /*********************************************************************** * PSDRV_GetFontMetric */ -static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *afm, - NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) +static UINT PSDRV_GetFontMetric( PSDRV_PDEVICE *physDev, const AFM *afm, + NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) { /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */ @@ -417,7 +417,7 @@ static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *afm, /*********************************************************************** * PSDRV_EnumDeviceFonts */ -BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, +BOOL PSDRV_EnumDeviceFonts( PSDRV_PDEVICE *physDev, LPLOGFONTW plf, DEVICEFONTENUMPROC proc, LPARAM lp ) { ENUMLOGFONTEXW lf; @@ -425,14 +425,7 @@ BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, BOOL b, bRet = 0; AFMLISTENTRY *afmle; FONTFAMILY *family; - PSDRV_PDEVICE *physDev; char FaceName[LF_FACESIZE]; - DC *dc = DC_GetDCPtr( hdc ); - if (!dc) return FALSE; - - physDev = (PSDRV_PDEVICE *)dc->physDev; - /* FIXME!! should reevaluate dc->physDev after every callback */ - GDI_ReleaseObj( hdc ); if( plf->lfFaceName[0] ) { WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1, @@ -446,9 +439,7 @@ BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, if(family) { for(afmle = family->afmlist; afmle; afmle = afmle->next) { TRACE("Got '%s'\n", afmle->afm->FontName); - if( (b = (*proc)( &lf, &tm, - PSDRV_GetFontMetric( hdc, afmle->afm, &tm, &lf ), - lp )) ) + if( (b = proc( &lf, &tm, PSDRV_GetFontMetric(physDev, afmle->afm, &tm, &lf), lp )) ) bRet = b; else break; } @@ -459,9 +450,7 @@ BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, for(family = physDev->pi->Fonts; family; family = family->next) { afmle = family->afmlist; TRACE("Got '%s'\n", afmle->afm->FontName); - if( (b = (*proc)( &lf, &tm, - PSDRV_GetFontMetric( hdc, afmle->afm, &tm, &lf ), - lp )) ) + if( (b = proc( &lf, &tm, PSDRV_GetFontMetric(physDev, afmle->afm, &tm, &lf), lp )) ) bRet = b; else break; } diff --git a/dlls/wineps/psdrv.h b/dlls/wineps/psdrv.h index 3a6ff724b6..4ed007c266 100644 --- a/dlls/wineps/psdrv.h +++ b/dlls/wineps/psdrv.h @@ -401,7 +401,7 @@ extern BOOL PSDRV_Ellipse( PSDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom ); extern INT PSDRV_EndDoc( PSDRV_PDEVICE *physDev ); extern INT PSDRV_EndPage( PSDRV_PDEVICE *physDev ); -extern BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, +extern BOOL PSDRV_EnumDeviceFonts( PSDRV_PDEVICE *physDev, LPLOGFONTW plf, DEVICEFONTENUMPROC proc, LPARAM lp ); extern BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, diff --git a/dlls/wineps/wineps.spec b/dlls/wineps/wineps.spec index be7bbb8acc..d9440a2093 100644 --- a/dlls/wineps/wineps.spec +++ b/dlls/wineps/wineps.spec @@ -22,7 +22,7 @@ debug_channels (psdrv) @ cdecl Ellipse(ptr long long long long) PSDRV_Ellipse @ cdecl EndDoc(ptr) PSDRV_EndDoc @ cdecl EndPage(ptr) PSDRV_EndPage -@ cdecl EnumDeviceFonts(long ptr ptr long) PSDRV_EnumDeviceFonts +@ cdecl EnumDeviceFonts(ptr ptr ptr long) PSDRV_EnumDeviceFonts @ cdecl ExtDeviceMode(ptr long ptr ptr ptr ptr ptr long) PSDRV_ExtDeviceMode @ cdecl ExtEscape(ptr long long ptr long ptr) PSDRV_ExtEscape @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) PSDRV_ExtTextOut diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index 49978b0a17..d305a9a6a9 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -25,7 +25,7 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics @ cdecl DeleteObject(long) X11DRV_DeleteObject @ cdecl DescribePixelFormat(ptr long long ptr) X11DRV_DescribePixelFormat @ cdecl Ellipse(ptr long long long long) X11DRV_Ellipse -@ cdecl EnumDeviceFonts(long ptr ptr long) X11DRV_EnumDeviceFonts +@ cdecl EnumDeviceFonts(ptr ptr ptr long) X11DRV_EnumDeviceFonts @ cdecl ExtEscape(ptr long long ptr long ptr) X11DRV_ExtEscape @ cdecl ExtFloodFill(ptr long long long long) X11DRV_ExtFloodFill @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) X11DRV_ExtTextOut diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c index ab81a5e221..8297a1b277 100644 --- a/graphics/x11drv/xfont.c +++ b/graphics/x11drv/xfont.c @@ -3313,23 +3313,17 @@ HFONT X11DRV_SelectFont( X11DRV_PDEVICE *physDev, HFONT hfont ) * * X11DRV_EnumDeviceFonts */ -BOOL X11DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, +BOOL X11DRV_EnumDeviceFonts( X11DRV_PDEVICE *physDev, LPLOGFONTW plf, DEVICEFONTENUMPROC proc, LPARAM lp ) { ENUMLOGFONTEXW lf; NEWTEXTMETRICEXW tm; fontResource* pfr = fontList; - BOOL b, bRet = 0, using_gdi = 0; + BOOL b, bRet = 0; LOGFONT16 lf16; - DC *dc; - - dc = DC_GetDCPtr(hdc); - if(!dc) return FALSE; - if(dc->gdiFont) using_gdi = TRUE; - GDI_ReleaseObj(hdc); /* don't enumerate x11 fonts if we're using client side fonts */ - if(using_gdi) return FALSE; + if (physDev->dc->gdiFont) return FALSE; FONT_LogFontWTo16(plf, &lf16); diff --git a/include/gdi.h b/include/gdi.h index 58052f3df2..38eaf36c65 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -162,7 +162,7 @@ typedef struct tagDC_FUNCS INT (*pEndDoc)(PHYSDEV); INT (*pEndPage)(PHYSDEV); BOOL (*pEndPath)(PHYSDEV); - BOOL (*pEnumDeviceFonts)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM); + BOOL (*pEnumDeviceFonts)(PHYSDEV,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM); INT (*pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT); INT (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD); INT (*pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID); diff --git a/include/x11drv.h b/include/x11drv.h index 433181573a..83037b3ad6 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -108,7 +108,7 @@ extern unsigned int X11DRV_server_startticks; extern BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT width, INT height, X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, DWORD rop ); -extern BOOL X11DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, +extern BOOL X11DRV_EnumDeviceFonts( X11DRV_PDEVICE *physDev, LPLOGFONTW plf, DEVICEFONTENUMPROC dfeproc, LPARAM lp ); extern BOOL X11DRV_GetCharWidth( X11DRV_PDEVICE *physDev, UINT firstChar, UINT lastChar, LPINT buffer ); diff --git a/objects/font.c b/objects/font.c index ecadda517f..17ecc9fcce 100644 --- a/objects/font.c +++ b/objects/font.c @@ -46,6 +46,9 @@ typedef struct LPENUMLOGFONTEX16 lpLogFont; SEGPTR segTextMetric; SEGPTR segLogFont; + HDC hdc; + DC *dc; + PHYSDEV physDev; } fontEnum16; typedef struct @@ -54,6 +57,9 @@ typedef struct FONTENUMPROCEXW lpEnumFunc; LPARAM lpData; DWORD dwFlags; + HDC hdc; + DC *dc; + PHYSDEV physDev; } fontEnum32; /* @@ -642,18 +648,29 @@ INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer ) static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm, DWORD fType, LPARAM lp ) { -#define pfe ((fontEnum16*)lp) + fontEnum16 *pfe = (fontEnum16*)lp; + INT ret = 1; + DC *dc; + if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet ) { FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont); FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric); + GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */ - return FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric, - (UINT16)fType, (LPARAM)pfe->lpData ); + ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric, + (UINT16)fType, (LPARAM)pfe->lpData ); + /* 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) + { + if (dc) GDI_ReleaseObj( pfe->hdc ); + pfe->hdc = 0; /* make sure we don't try to release it later on */ + ret = 0; + } } -#undef pfe - return 1; + return ret; } /*********************************************************************** @@ -662,34 +679,40 @@ static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm, static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm, DWORD fType, LPARAM lp ) { - /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */ + fontEnum32 *pfe = (fontEnum32*)lp; + INT ret = 1; + DC *dc; -#define pfe ((fontEnum32*)lp) + /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */ if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet ) { /* convert font metrics */ + ENUMLOGFONTEXA logfont; + NEWTEXTMETRICEXA tmA; pfe->dwFlags |= ENUM_CALLED; - if( pfe->dwFlags & ENUM_UNICODE ) - { - return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData ); - } - else - { - ENUMLOGFONTEXA logfont; - NEWTEXTMETRICEXA tmA; + if (!(pfe->dwFlags & ENUM_UNICODE)) + { + FONT_EnumLogFontExWToA( plf, &logfont); + FONT_NewTextMetricExWToA( ptm, &tmA ); + plf = (LPENUMLOGFONTEXW)&logfont; + ptm = (LPNEWTEXTMETRICEXW)&tmA; + } + GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */ - FONT_EnumLogFontExWToA( plf, &logfont); - FONT_NewTextMetricExWToA( ptm, &tmA ); + ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData ); - return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, - (LPNEWTEXTMETRICEXW)&tmA, fType, - pfe->lpData ); - } + /* 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) + { + if (dc) GDI_ReleaseObj( pfe->hdc ); + pfe->hdc = 0; /* make sure we don't try to release it later on */ + ret = 0; + } } -#undef pfe - return 1; + return ret; } /*********************************************************************** @@ -699,19 +722,19 @@ INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf, FONTENUMPROCEX16 efproc, LPARAM lParam, DWORD dwFlags) { - BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM); + fontEnum16 fe16; INT16 retVal = 0; DC* dc = DC_GetDCPtr( hDC ); if (!dc) return 0; - enum_func = dc->funcs->pEnumDeviceFonts; - GDI_ReleaseObj( hDC ); + fe16.hdc = hDC; + fe16.dc = dc; + fe16.physDev = dc->physDev; - if (enum_func) + if (dc->funcs->pEnumDeviceFonts) { NEWTEXTMETRICEX16 tm16; ENUMLOGFONTEX16 lf16; - fontEnum16 fe16; LOGFONTW lfW; FONT_LogFont16ToW(plf, &lfW); @@ -723,10 +746,12 @@ INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf, fe16.segTextMetric = MapLS( &tm16 ); fe16.segLogFont = MapLS( &lf16 ); - retVal = enum_func( hDC, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 ); + retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, + FONT_EnumInstance16, (LPARAM)&fe16 ); UnMapLS( fe16.segTextMetric ); UnMapLS( fe16.segLogFont ); } + if (fe16.hdc) GDI_ReleaseObj( fe16.hdc ); return retVal; } @@ -737,7 +762,6 @@ static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc, LPARAM lParam, DWORD dwUnicode) { - BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM); INT ret = 1, ret2; DC *dc = DC_GetDCPtr( hDC ); fontEnum32 fe32; @@ -751,21 +775,28 @@ static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, fe32.lpEnumFunc = efproc; fe32.lpData = lParam; fe32.dwFlags = dwUnicode; + fe32.hdc = hDC; + fe32.dc = dc; + fe32.physDev = dc->physDev; - enum_func = dc->funcs->pEnumDeviceFonts; - GDI_ReleaseObj( hDC ); enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE; - if (!enum_func && !enum_gdi_fonts) return 0; - + if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts) + { + ret = 0; + goto done; + } + if (enum_gdi_fonts) ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 ); fe32.dwFlags &= ~ENUM_CALLED; - if (ret && enum_func) { - ret2 = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 ); + if (ret && dc->funcs->pEnumDeviceFonts) { + ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 ); if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */ ret = ret2; } + done: + if (fe32.hdc) GDI_ReleaseObj( fe32.hdc ); return ret; }