From: Jacek Caban jacek@codeweavers.com
And use it for GetCharWidthA.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- 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 */