gdi32: Use NtGdiEnumFonts for EnumFontFamiliesExW.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-09-01 14:08:27 +02:00 committed by Alexandre Julliard
parent 931ea8b00e
commit 865be24a25
3 changed files with 98 additions and 54 deletions

View file

@ -196,15 +196,6 @@ typedef struct
LOGFONTW logfont;
} FONTOBJ;
struct font_enum
{
LPLOGFONTW lpLogFontParam;
FONTENUMPROCW lpEnumFunc;
LPARAM lpData;
HDC hdc;
INT retval;
};
/*
* For TranslateCharsetInfo
*/
@ -4315,64 +4306,65 @@ static BOOL FONT_DeleteObject( HGDIOBJ handle )
}
/***********************************************************************
* FONT_EnumInstance
*
* Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
* We have to use other types because of the FONTENUMPROCW definition.
*/
static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *ptm,
DWORD fType, LPARAM lp )
struct font_enum
{
struct font_enum *pfe = (struct font_enum *)lp;
INT ret = 1;
HDC hdc;
struct font_enum_entry *buf;
ULONG size;
ULONG count;
ULONG charset;
};
/* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
if ((!pfe->lpLogFontParam ||
pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) &&
(!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) )
static INT WINAPI font_enum_proc( const LOGFONTW *lf, const TEXTMETRICW *tm,
DWORD type, LPARAM lp )
{
ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
pfe->retval = ret;
struct font_enum *fe = (struct font_enum *)lp;
if (fe->charset != DEFAULT_CHARSET && lf->lfCharSet != fe->charset) return 1;
if ((type & RASTER_FONTTYPE) && !(NtGdiGetDeviceCaps( fe->hdc, TEXTCAPS ) & TC_RA_ABLE))
return 1;
if (fe->buf && fe->count < fe->size)
{
fe->buf[fe->count].type = type;
fe->buf[fe->count].lf = *(const ENUMLOGFONTEXW *)lf;
fe->buf[fe->count].tm = *(const NEWTEXTMETRICEXW *)tm;
}
return ret;
fe->count++;
return 1;
}
/***********************************************************************
* FONT_EnumFontFamiliesEx
* NtGdiEnumFonts (win32u.@)
*/
static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCW efproc,
LPARAM lParam )
BOOL WINAPI NtGdiEnumFonts( HDC hdc, ULONG type, ULONG win32_compat, ULONG face_name_len,
const WCHAR *face_name, ULONG charset, ULONG *count, void *buf )
{
INT ret = 0;
DC *dc = get_dc_ptr( hDC );
struct font_enum fe;
PHYSDEV physdev;
LOGFONTW lf;
BOOL ret;
DC *dc;
if (dc)
{
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pEnumFonts );
if (!(dc = get_dc_ptr( hdc ))) return 0;
memset( &lf, 0, sizeof(lf) );
lf.lfCharSet = charset;
if (face_name_len) memcpy( lf.lfFaceName, face_name, face_name_len * sizeof(WCHAR) );
fe.hdc = hdc;
fe.buf = buf;
fe.size = *count / sizeof(*fe.buf);
fe.count = 0;
fe.charset = charset;
physdev = GET_DC_PHYSDEV( dc, pEnumFonts );
ret = physdev->funcs->pEnumFonts( physdev, &lf, font_enum_proc, (LPARAM)&fe );
if (ret && buf) ret = fe.count <= fe.size;
*count = fe.count * sizeof(*fe.buf);
if (plf) TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName), plf->lfCharSet);
fe.lpLogFontParam = plf;
fe.lpEnumFunc = efproc;
fe.lpData = lParam;
fe.hdc = hDC;
fe.retval = 1;
ret = physdev->funcs->pEnumFonts( physdev, plf, FONT_EnumInstance, (LPARAM)&fe );
release_dc_ptr( dc );
}
return ret ? fe.retval : 0;
}
/***********************************************************************
* EnumFontFamiliesExW (GDI32.@)
*/
INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
FONTENUMPROCW efproc,
LPARAM lParam, DWORD dwFlags )
{
return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam );
return ret;
}

View file

@ -2037,6 +2037,49 @@ BOOL WINAPI GdiRealizationInfo( HDC hdc, struct realization_info *info )
return TRUE;
}
/***********************************************************************
* EnumFontFamiliesExW (GDI32.@)
*/
INT WINAPI EnumFontFamiliesExW( HDC hdc, LOGFONTW *lf, FONTENUMPROCW efproc,
LPARAM lparam, DWORD flags )
{
struct font_enum_entry buf[32], *entries = buf;
const WCHAR *face_name = NULL;
DWORD charset, face_name_len = 0;
ULONG count, i;
INT ret = 1;
if (lf)
{
if (lf->lfFaceName[0])
{
face_name = lf->lfFaceName;
face_name_len = lstrlenW( face_name );
}
charset = lf->lfCharSet;
}
else charset = DEFAULT_CHARSET;
count = sizeof(buf);
if (!NtGdiEnumFonts( hdc, 0, 0, face_name_len, face_name, charset, &count, buf ) &&
count <= sizeof(buf))
return 0;
if (count > sizeof(buf))
{
if (!(entries = HeapAlloc( GetProcessHeap(), 0, count ))) return 0;
ret = NtGdiEnumFonts( hdc, 0, 0, face_name_len, face_name, charset, &count, entries );
}
count /= sizeof(*entries);
for (i = 0; ret && i < count; i++)
{
ret = efproc( (const LOGFONTW *)&entries[i].lf, (const TEXTMETRICW *)&entries[i].tm,
entries[i].type, lparam );
}
if (entries != buf) HeapFree( GetProcessHeap(), 0, entries );
return ret;
}
struct enum_proc_paramsWtoA
{
LPARAM lparam;

View file

@ -171,6 +171,13 @@ typedef struct DC_ATTR
void *emf;
} DC_ATTR;
struct font_enum_entry
{
DWORD type;
ENUMLOGFONTEXW lf;
NEWTEXTMETRICEXW tm;
};
#endif /* __WINESRC__ */
struct font_realization_info
@ -259,6 +266,8 @@ HRGN WINAPI NtGdiExtCreateRegion( const XFORM *xform, DWORD count, const RGN
INT WINAPI NtGdiExtGetObjectW( HGDIOBJ handle, INT count, void *buffer );
INT WINAPI NtGdiExtSelectClipRgn( HDC hdc, HRGN region, INT mode );
BOOL WINAPI NtGdiFillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush );
BOOL WINAPI NtGdiEnumFonts( HDC hdc, ULONG type, ULONG win32_compat, ULONG face_name_len,
const WCHAR *face_name, ULONG charset, ULONG *count, void *buf );
INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, INT driver_id, INT escape, INT input_size,
const char *input, INT output_size, char *output );
BOOL WINAPI NtGdiExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, UINT type );