Pass a PHYSDEV to EnumDeviceFont and release the GDI lock in

FONT_EnumInstance instead.
This commit is contained in:
Alexandre Julliard 2002-04-14 19:42:43 +00:00
parent eac3662bc7
commit ab246a679b
10 changed files with 85 additions and 76 deletions

View File

@ -194,22 +194,16 @@ BOOL WIN16DRV_GetCharWidth( PHYSDEV dev, UINT firstChar, UINT lastChar,
* WIN16DRV_EnumDeviceFonts
*/
BOOL WIN16DRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf,
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;

View File

@ -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,

View File

@ -386,7 +386,7 @@ BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev )
/***********************************************************************
* PSDRV_GetFontMetric
*/
static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *afm,
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;
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 );

View File

@ -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,
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 */
pfe->dwFlags |= ENUM_CALLED;
if( pfe->dwFlags & ENUM_UNICODE )
{
return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
}
else
{
ENUMLOGFONTEXA logfont;
NEWTEXTMETRICEXA tmA;
pfe->dwFlags |= ENUM_CALLED;
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 */
return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
(LPNEWTEXTMETRICEXW)&tmA, fType,
pfe->lpData );
ret = pfe->lpEnumFunc( plf, ptm, 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;
}