Jacek Caban : gdi32: Support passing an array of chars to NtGdiGetCharWidthW.
Alexandre Julliard
julliard at winehq.org
Thu Aug 26 15:22:31 CDT 2021
Module: wine
Branch: master
Commit: 2c77643ee9d22295bbd7a0482009b7d8d3907fbf
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2c77643ee9d22295bbd7a0482009b7d8d3907fbf
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Aug 26 13:45:15 2021 +0100
gdi32: Support passing an array of chars to NtGdiGetCharWidthW.
And use it for GetCharWidthA.
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/driver.c | 3 ++-
dlls/gdi32/font.c | 29 ++++++++++++++++-------------
dlls/gdi32/text.c | 38 ++++++++++++--------------------------
dlls/wineps.drv/builtin.c | 24 +++++++++++++-----------
dlls/wineps.drv/psdrv.h | 2 +-
include/wine/gdi_driver.h | 4 ++--
6 files changed, 46 insertions(+), 54 deletions(-)
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index f370d088585..3d64eedc638 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -380,7 +380,8 @@ static BOOL CDECL nulldrv_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count
return FALSE;
}
-static BOOL CDECL nulldrv_GetCharWidth( PHYSDEV dev, UINT first, UINT last, INT *buffer )
+static BOOL CDECL nulldrv_GetCharWidth( PHYSDEV dev, UINT first, UINT count,
+ const WCHAR *chars, INT *buffer )
{
return FALSE;
}
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index c88e69ef013..7e4d67af8ae 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -3089,27 +3089,29 @@ static BOOL CDECL font_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count, W
/*************************************************************
* font_GetCharWidth
*/
-static BOOL CDECL font_GetCharWidth( PHYSDEV dev, UINT first, UINT last, INT *buffer )
+static BOOL CDECL font_GetCharWidth( PHYSDEV dev, UINT first, UINT count,
+ const WCHAR *chars, INT *buffer )
{
struct font_physdev *physdev = get_font_dev( dev );
+ UINT c, i;
ABC abc;
- UINT c;
if (!physdev->font)
{
dev = GET_NEXT_PHYSDEV( dev, pGetCharWidth );
- return dev->funcs->pGetCharWidth( dev, first, last, buffer );
+ return dev->funcs->pGetCharWidth( dev, first, count, chars, buffer );
}
- TRACE( "%p, %d, %d, %p\n", physdev->font, first, last, buffer );
+ TRACE( "%p, %d, %d, %p\n", physdev->font, first, count, buffer );
EnterCriticalSection( &font_cs );
- for (c = first; c <= last; c++)
+ for (i = 0; i < count; i++)
{
+ c = chars ? chars[i] : i + first;
if (get_glyph_outline( physdev->font, c, GGO_METRICS, NULL, &abc, 0, NULL, NULL ) == GDI_ERROR)
- buffer[c - first] = 0;
+ buffer[i] = 0;
else
- buffer[c - first] = abc.abcA + abc.abcB + abc.abcC;
+ buffer[i] = abc.abcA + abc.abcB + abc.abcC;
}
LeaveCriticalSection( &font_cs );
return TRUE;
@@ -4864,25 +4866,26 @@ static LPSTR FONT_GetCharsByRangeA(HDC hdc, UINT firstChar, UINT lastChar, PINT
/***********************************************************************
* NtGdiGetCharWidthW (win32u.@)
*/
-BOOL WINAPI NtGdiGetCharWidthW( HDC hdc, UINT firstChar, UINT lastChar, WCHAR *chars,
+BOOL WINAPI NtGdiGetCharWidthW( HDC hdc, UINT first, UINT last, WCHAR *chars,
ULONG flags, void *buf )
{
- UINT i;
+ UINT i, count = last;
BOOL ret;
PHYSDEV dev;
DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE;
+ if (!chars) count = last - first + 1;
dev = GET_DC_PHYSDEV( dc, pGetCharWidth );
- ret = dev->funcs->pGetCharWidth( dev, firstChar, lastChar, buf );
+ ret = dev->funcs->pGetCharWidth( dev, first, count, chars, buf );
if (ret)
{
INT *buffer = buf;
/* convert device units to logical */
- for( i = firstChar; i <= lastChar; i++, buffer++ )
- *buffer = width_to_LP( dc, *buffer );
+ for (i = 0; i < count; i++)
+ buffer[i] = width_to_LP( dc, buffer[i] );
}
release_dc_ptr( dc );
return ret;
@@ -6479,7 +6482,7 @@ BOOL WINAPI GetCharWidthFloatW( HDC hdc, UINT first, UINT last, float *buffer )
}
dev = GET_DC_PHYSDEV( dc, pGetCharWidth );
- if ((ret = dev->funcs->pGetCharWidth( dev, first, last, ibuffer )))
+ if ((ret = dev->funcs->pGetCharWidth( dev, first, last - first + 1, NULL, ibuffer )))
{
float scale = fabs( dc->xformVport2World.eM11 ) / 16.0f;
for (i = first; i <= last; ++i)
diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c
index 167aa5cc07d..0bb47f00c24 100644
--- a/dlls/gdi32/text.c
+++ b/dlls/gdi32/text.c
@@ -1580,12 +1580,13 @@ BOOL WINAPI GetCharWidth32W( HDC hdc, UINT first, UINT last, INT *buffer )
return NtGdiGetCharWidthW( hdc, first, last, NULL, NTGDI_GETCHARWIDTH_INT, buffer );
}
-static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len )
+static WCHAR *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *ret_len )
{
INT i, count = last - first + 1;
+ WCHAR *wstr;
+ char *str;
UINT mbcp;
UINT c;
- LPSTR str;
if (count <= 0)
return NULL;
@@ -1628,8 +1629,9 @@ static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len )
}
str[i] = '\0';
- *byte_len = i;
- return str;
+ wstr = text_mbtowc( hdc, str, i, ret_len, NULL );
+ HeapFree( GetProcessHeap(), 0, str );
+ return wstr;
}
/***********************************************************************
@@ -1638,28 +1640,12 @@ static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len )
*/
BOOL WINAPI GetCharWidth32A( HDC hdc, UINT first, UINT last, INT *buffer )
{
- INT i, wlen;
- LPSTR str;
- LPWSTR wstr;
- BOOL ret = TRUE;
-
- str = get_chars_by_range( hdc, first, last, &i );
- if (str == NULL)
- return FALSE;
-
- wstr = text_mbtowc( hdc, str, i, &wlen, NULL );
-
- for(i = 0; i < wlen; i++)
- {
- if(!GetCharWidth32W( hdc, wstr[i], wstr[i], buffer ))
- {
- ret = FALSE;
- break;
- }
- buffer++;
- }
+ WCHAR *chars;
+ INT count;
+ BOOL ret;
- HeapFree( GetProcessHeap(), 0, str );
- HeapFree( GetProcessHeap(), 0, wstr );
+ if (!(chars = get_chars_by_range( hdc, first, last, &count ))) return FALSE;
+ ret = NtGdiGetCharWidthW( hdc, 0, count, chars, NTGDI_GETCHARWIDTH_INT, buffer );
+ HeapFree( GetProcessHeap(), 0, chars );
return ret;
}
diff --git a/dlls/wineps.drv/builtin.c b/dlls/wineps.drv/builtin.c
index 22397567aa4..11ba2154148 100644
--- a/dlls/wineps.drv/builtin.c
+++ b/dlls/wineps.drv/builtin.c
@@ -343,28 +343,30 @@ BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT
/***********************************************************************
* PSDRV_GetCharWidth
*/
-BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT firstChar, UINT lastChar, LPINT buffer)
+BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer)
{
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
- UINT i;
+ UINT i, c;
if (physDev->font.fontloc == Download)
{
dev = GET_NEXT_PHYSDEV( dev, pGetCharWidth );
- return dev->funcs->pGetCharWidth( dev, firstChar, lastChar, buffer );
+ return dev->funcs->pGetCharWidth( dev, first, count, chars, buffer );
}
- TRACE("U+%.4X U+%.4X\n", firstChar, lastChar);
+ TRACE("U+%.4X +%u\n", first, count);
- if (lastChar > 0xffff || firstChar > lastChar)
+ for (i = 0; i < count; ++i)
{
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ c = chars ? chars[i] : first + i;
- for (i = firstChar; i <= lastChar; ++i)
- {
- *buffer = floor( PSDRV_UVMetrics(i, physDev->font.fontinfo.Builtin.afm)->WX
+ if (c > 0xffff)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ *buffer = floor( PSDRV_UVMetrics(c, physDev->font.fontinfo.Builtin.afm)->WX
* physDev->font.fontinfo.Builtin.scale + 0.5 );
TRACE("U+%.4X: %i\n", i, *buffer);
++buffer;
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 84828a5c9ce..db7c6e37f7c 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -439,7 +439,7 @@ extern INT CDECL PSDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID
extern BOOL CDECL PSDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx ) DECLSPEC_HIDDEN;
extern BOOL CDECL PSDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
-extern BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT firstChar, UINT lastChar, LPINT buffer) DECLSPEC_HIDDEN;
+extern BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) DECLSPEC_HIDDEN;
extern BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT alpDx) DECLSPEC_HIDDEN;
extern BOOL CDECL PSDRV_GetTextMetrics(PHYSDEV dev, TEXTMETRICW *metrics) DECLSPEC_HIDDEN;
extern BOOL CDECL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN;
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 5ca84ccf56c..6db6cf94b70 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -99,7 +99,7 @@ struct gdi_dc_funcs
UINT (CDECL *pGetBoundsRect)(PHYSDEV,RECT*,UINT);
BOOL (CDECL *pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
BOOL (CDECL *pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,LPABC);
- BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
+ BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,const WCHAR*,LPINT);
BOOL (CDECL *pGetCharWidthInfo)(PHYSDEV,void*);
INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT);
BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
@@ -169,7 +169,7 @@ struct gdi_dc_funcs
};
/* increment this when you change the DC function table */
-#define WINE_GDI_DRIVER_VERSION 64
+#define WINE_GDI_DRIVER_VERSION 65
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */
#define GDI_PRIORITY_FONT_DRV 100 /* any font driver */
More information about the wine-cvs
mailing list