Jacek Caban : gdi32: Use NtGdiEnumFonts for EnumFontFamiliesExW.

Alexandre Julliard julliard at winehq.org
Wed Sep 1 15:45:10 CDT 2021


Module: wine
Branch: master
Commit: 865be24a2516518250badb5325220eacff2a126f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=865be24a2516518250badb5325220eacff2a126f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep  1 14:08:27 2021 +0200

gdi32: Use NtGdiEnumFonts for EnumFontFamiliesExW.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/font.c | 100 +++++++++++++++++++++++++-----------------------------
 dlls/gdi32/text.c |  43 +++++++++++++++++++++++
 include/ntgdi.h   |   9 +++++
 3 files changed, 98 insertions(+), 54 deletions(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 5e9cefa0c7d..ef57c4f9e49 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -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;
+};
+
+static INT WINAPI font_enum_proc( const LOGFONTW *lf, const TEXTMETRICW *tm,
+                                  DWORD type, LPARAM lp )
+{
+    struct font_enum *fe = (struct font_enum *)lp;
 
-    /* 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) )
+    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)
     {
-        ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
-        pfe->retval = ret;
+        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;
 
-        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;
-}
+    memset( &lf, 0, sizeof(lf) );
+    lf.lfCharSet = charset;
+    if (face_name_len) memcpy( lf.lfFaceName, face_name, face_name_len * sizeof(WCHAR) );
 
-/***********************************************************************
- *              EnumFontFamiliesExW	(GDI32.@)
- */
-INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
-                                    FONTENUMPROCW efproc,
-                                    LPARAM lParam, DWORD dwFlags )
-{
-    return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam );
+    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);
+
+    release_dc_ptr( dc );
+    return ret;
 }
 
 
diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c
index d500a19a65a..8cc6ec25353 100644
--- a/dlls/gdi32/text.c
+++ b/dlls/gdi32/text.c
@@ -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;
diff --git a/include/ntgdi.h b/include/ntgdi.h
index f03b12a09ae..a3cf54d785a 100644
--- a/include/ntgdi.h
+++ b/include/ntgdi.h
@@ -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 );




More information about the wine-cvs mailing list