Commit 2938242b authored by Huw D M Davies's avatar Huw D M Davies Committed by Alexandre Julliard

Use the font charset to obtain a codepage for A->W conversion in the

text functions.
parent ee0c4f86
......@@ -71,6 +71,8 @@ extern void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W
extern void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16*, LPNEWTEXTMETRICEXW);
extern void FONT_EnumLogFontEx16ToW(const ENUMLOGFONTEX16*, LPENUMLOGFONTEXW);
extern LPWSTR FONT_mbtowc(HDC, LPCSTR, INT, INT*, UINT*);
extern DWORD WineEngAddRefFont(GdiFont);
extern GdiFont WineEngCreateFontInstance(HFONT);
extern DWORD WineEngDecRefFont(GdiFont);
......
......@@ -1032,12 +1032,10 @@ BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
LPSIZE size )
{
BOOL ret = FALSE;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
INT wlen;
LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
if (p) {
wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
ret = GetTextExtentPoint32W( hdc, p, wlen, size );
HeapFree( GetProcessHeap(), 0, p );
}
......@@ -1109,11 +1107,9 @@ BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
LPINT alpDx, LPSIZE size )
{
BOOL ret;
DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
INT wlen;
LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
HeapFree( GetProcessHeap(), 0, p );
return ret;
}
......
......@@ -18,10 +18,76 @@
DEFAULT_DEBUG_CHANNEL(text);
/***********************************************************************
* ExtTextOut (GDI.351)
* FONT_mbtowc
*
* Returns a '\0' terminated Unicode translation of str using the
* charset of the currently selected font in hdc. If count is -1 then
* str is assumed to be '\0' terminated, otherwise it contains the
* number of bytes to convert. If plenW is non-NULL, on return it
* will point to the number of WCHARs (excluding the '\0') that have
* been written. If pCP is non-NULL, on return it will point to the
* codepage used in the conversion. The caller should free the
* returned LPWSTR from the process heap itself.
*/
LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
{
LOGFONTW lf;
UINT cp = CP_ACP;
INT lenW;
LPWSTR strW;
CHARSETINFO csi;
GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
/* Hmm, nicely designed api this one! */
if(TranslateCharsetInfo((DWORD*)(UINT)lf.lfCharSet, &csi, TCI_SRCCHARSET))
cp = csi.ciACP;
else {
switch(lf.lfCharSet) {
case SYMBOL_CHARSET:
cp = CP_SYMBOL;
break;
case OEM_CHARSET:
cp = GetOEMCP();
break;
case VISCII_CHARSET:
case TCVN_CHARSET:
case KOI8_CHARSET:
case ISO3_CHARSET:
case ISO4_CHARSET:
case ISO10_CHARSET:
case CELTIC_CHARSET:
/* FIXME: These have no place here, but becasue x11drv
enumerates fonts with these (made up) charsets some apps
might use them and then the FIXME below would become
annoying. Now we could pick the intended codepage for
each of these, but since it's broken anyway we'll just
use CP_ACP and hope it'll go away...
*/
cp = CP_ACP;
break;
default:
FIXME("Can't find codepage for charset %d\n", lf.lfCharSet);
break;
}
}
lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
MultiByteToWideChar(cp, 0, str, count, strW, lenW);
strW[lenW] = '\0';
if(plenW) *plenW = lenW;
if(pCP) *pCP = cp;
return strW;
}
/***********************************************************************
* ExtTextOut (GDI.351)
*/
BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
const RECT16 *lprect, LPCSTR str, UINT16 count,
const INT16 *lpDx )
......@@ -47,48 +113,33 @@ BOOL16 WINAPI ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
* ExtTextOutA (GDI32.@)
*/
BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
const RECT *lprect, LPCSTR str, UINT count,
const INT *lpDx )
const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
{
DC * dc = DC_GetDCUpdate( hdc );
LPWSTR p;
UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
BOOL ret = FALSE;
INT wlen;
UINT codepage;
LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
BOOL ret;
LPINT lpDxW = NULL;
if (!dc) return FALSE;
if (lpDx) {
unsigned int i = 0, j = 0;
if (dc->funcs->pExtTextOut)
{
UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
if (lpDx)
{
unsigned int i = 0, j = 0;
lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
while(i < count)
{
if(IsDBCSLeadByteEx(codepage, str[i]))
{
lpDxW[j++] = lpDx[i] + lpDx[i+1];
i = i + 2;
}
else
{
lpDxW[j++] = lpDx[i];
i = i + 1;
}
}
}
if ((p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) )))
{
wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
ret = dc->funcs->pExtTextOut( dc, x, y, flags, lprect, p, wlen, lpDxW );
HeapFree( GetProcessHeap(), 0, p );
}
if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
while(i < count) {
if(IsDBCSLeadByteEx(codepage, str[i])) {
lpDxW[j++] = lpDx[i] + lpDx[i+1];
i = i + 2;
} else {
lpDxW[j++] = lpDx[i];
i = i + 1;
}
}
}
GDI_ReleaseObj( hdc );
ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
HeapFree( GetProcessHeap(), 0, p );
if (lpDxW) HeapFree( GetProcessHeap(), 0, lpDxW );
return ret;
}
......@@ -97,8 +148,7 @@ BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
* ExtTextOutW (GDI32.@)
*/
BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR str, UINT count,
const INT *lpDx )
const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
{
BOOL ret = FALSE;
DC * dc = DC_GetDCUpdate( hdc );
......
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