Commit 2c77643e authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

gdi32: Support passing an array of chars to NtGdiGetCharWidthW.

And use it for GetCharWidthA. Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent baa60569
...@@ -380,7 +380,8 @@ static BOOL CDECL nulldrv_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count ...@@ -380,7 +380,8 @@ static BOOL CDECL nulldrv_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count
return FALSE; 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; return FALSE;
} }
......
...@@ -3089,27 +3089,29 @@ static BOOL CDECL font_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count, W ...@@ -3089,27 +3089,29 @@ static BOOL CDECL font_GetCharABCWidthsI( PHYSDEV dev, UINT first, UINT count, W
/************************************************************* /*************************************************************
* font_GetCharWidth * 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 ); struct font_physdev *physdev = get_font_dev( dev );
UINT c, i;
ABC abc; ABC abc;
UINT c;
if (!physdev->font) if (!physdev->font)
{ {
dev = GET_NEXT_PHYSDEV( dev, pGetCharWidth ); 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 ); 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) if (get_glyph_outline( physdev->font, c, GGO_METRICS, NULL, &abc, 0, NULL, NULL ) == GDI_ERROR)
buffer[c - first] = 0; buffer[i] = 0;
else else
buffer[c - first] = abc.abcA + abc.abcB + abc.abcC; buffer[i] = abc.abcA + abc.abcB + abc.abcC;
} }
LeaveCriticalSection( &font_cs ); LeaveCriticalSection( &font_cs );
return TRUE; return TRUE;
...@@ -4864,25 +4866,26 @@ static LPSTR FONT_GetCharsByRangeA(HDC hdc, UINT firstChar, UINT lastChar, PINT ...@@ -4864,25 +4866,26 @@ static LPSTR FONT_GetCharsByRangeA(HDC hdc, UINT firstChar, UINT lastChar, PINT
/*********************************************************************** /***********************************************************************
* NtGdiGetCharWidthW (win32u.@) * 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 ) ULONG flags, void *buf )
{ {
UINT i; UINT i, count = last;
BOOL ret; BOOL ret;
PHYSDEV dev; PHYSDEV dev;
DC * dc = get_dc_ptr( hdc ); DC * dc = get_dc_ptr( hdc );
if (!dc) return FALSE; if (!dc) return FALSE;
if (!chars) count = last - first + 1;
dev = GET_DC_PHYSDEV( dc, pGetCharWidth ); 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) if (ret)
{ {
INT *buffer = buf; INT *buffer = buf;
/* convert device units to logical */ /* convert device units to logical */
for( i = firstChar; i <= lastChar; i++, buffer++ ) for (i = 0; i < count; i++)
*buffer = width_to_LP( dc, *buffer ); buffer[i] = width_to_LP( dc, buffer[i] );
} }
release_dc_ptr( dc ); release_dc_ptr( dc );
return ret; return ret;
...@@ -6479,7 +6482,7 @@ BOOL WINAPI GetCharWidthFloatW( HDC hdc, UINT first, UINT last, float *buffer ) ...@@ -6479,7 +6482,7 @@ BOOL WINAPI GetCharWidthFloatW( HDC hdc, UINT first, UINT last, float *buffer )
} }
dev = GET_DC_PHYSDEV( dc, pGetCharWidth ); 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; float scale = fabs( dc->xformVport2World.eM11 ) / 16.0f;
for (i = first; i <= last; ++i) for (i = first; i <= last; ++i)
......
...@@ -1580,12 +1580,13 @@ BOOL WINAPI GetCharWidth32W( HDC hdc, UINT first, UINT last, INT *buffer ) ...@@ -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 ); 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; INT i, count = last - first + 1;
WCHAR *wstr;
char *str;
UINT mbcp; UINT mbcp;
UINT c; UINT c;
LPSTR str;
if (count <= 0) if (count <= 0)
return NULL; return NULL;
...@@ -1628,8 +1629,9 @@ static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len ) ...@@ -1628,8 +1629,9 @@ static char *get_chars_by_range( HDC hdc, UINT first, UINT last, INT *byte_len )
} }
str[i] = '\0'; str[i] = '\0';
*byte_len = i; wstr = text_mbtowc( hdc, str, i, ret_len, NULL );
return str; 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 ) ...@@ -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 ) BOOL WINAPI GetCharWidth32A( HDC hdc, UINT first, UINT last, INT *buffer )
{ {
INT i, wlen; WCHAR *chars;
LPSTR str; INT count;
LPWSTR wstr; BOOL ret;
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++;
}
HeapFree( GetProcessHeap(), 0, str ); if (!(chars = get_chars_by_range( hdc, first, last, &count ))) return FALSE;
HeapFree( GetProcessHeap(), 0, wstr ); ret = NtGdiGetCharWidthW( hdc, 0, count, chars, NTGDI_GETCHARWIDTH_INT, buffer );
HeapFree( GetProcessHeap(), 0, chars );
return ret; return ret;
} }
...@@ -343,28 +343,30 @@ BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT ...@@ -343,28 +343,30 @@ BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT
/*********************************************************************** /***********************************************************************
* PSDRV_GetCharWidth * 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 ); PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
UINT i; UINT i, c;
if (physDev->font.fontloc == Download) if (physDev->font.fontloc == Download)
{ {
dev = GET_NEXT_PHYSDEV( dev, pGetCharWidth ); 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); c = chars ? chars[i] : first + i;
return FALSE;
}
for (i = firstChar; i <= lastChar; ++i) if (c > 0xffff)
{ {
*buffer = floor( PSDRV_UVMetrics(i, physDev->font.fontinfo.Builtin.afm)->WX SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
*buffer = floor( PSDRV_UVMetrics(c, physDev->font.fontinfo.Builtin.afm)->WX
* physDev->font.fontinfo.Builtin.scale + 0.5 ); * physDev->font.fontinfo.Builtin.scale + 0.5 );
TRACE("U+%.4X: %i\n", i, *buffer); TRACE("U+%.4X: %i\n", i, *buffer);
++buffer; ++buffer;
......
...@@ -439,7 +439,7 @@ extern INT CDECL PSDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID ...@@ -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, 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; 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_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_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_GetTextMetrics(PHYSDEV dev, TEXTMETRICW *metrics) DECLSPEC_HIDDEN;
extern BOOL CDECL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN;
......
...@@ -99,7 +99,7 @@ struct gdi_dc_funcs ...@@ -99,7 +99,7 @@ struct gdi_dc_funcs
UINT (CDECL *pGetBoundsRect)(PHYSDEV,RECT*,UINT); UINT (CDECL *pGetBoundsRect)(PHYSDEV,RECT*,UINT);
BOOL (CDECL *pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC); BOOL (CDECL *pGetCharABCWidths)(PHYSDEV,UINT,UINT,LPABC);
BOOL (CDECL *pGetCharABCWidthsI)(PHYSDEV,UINT,UINT,WORD*,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*); BOOL (CDECL *pGetCharWidthInfo)(PHYSDEV,void*);
INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT); INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT);
BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID); BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
...@@ -169,7 +169,7 @@ struct gdi_dc_funcs ...@@ -169,7 +169,7 @@ struct gdi_dc_funcs
}; };
/* increment this when you change the DC function table */ /* 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_NULL_DRV 0 /* null driver */
#define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment