From c8fb29311e6b6436c075977cfe74afd540ccdf3f Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 21 Jan 2006 00:52:08 +0000 Subject: [PATCH] Port Wine GetCharWidth32A. svn path=/trunk/; revision=20958 --- reactos/lib/gdi32/objects/font.c | 98 +++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/reactos/lib/gdi32/objects/font.c b/reactos/lib/gdi32/objects/font.c index bd458abd800..3909321df41 100644 --- a/reactos/lib/gdi32/objects/font.c +++ b/reactos/lib/gdi32/objects/font.c @@ -15,6 +15,73 @@ #define INITIAL_FAMILY_COUNT 64 +/*********************************************************************** + * FONT_mbtowc + * + * Returns a 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 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. + */ +static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP) +{ + UINT cp = CP_ACP; + INT lenW; + LPWSTR strW; + CHARSETINFO csi; + int charset = GetTextCharset(hdc); + + /* Hmm, nicely designed api this one! */ + if(NtGdiTranslateCharsetInfo((PDWORD)charset, &csi, TCI_SRCCHARSET)) + cp = csi.ciACP; + else { + switch(charset) { + case OEM_CHARSET: + cp = GetOEMCP(); + break; + case DEFAULT_CHARSET: + cp = GetACP(); + 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 because 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: + DPRINT1("Can't find codepage for charset %d\n", charset); + break; + } + } + + DPRINT("charset %d => cp %d\n", charset, cp); + + if(count == -1) count = strlen(str); + lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0); + strW = HeapAlloc(GetProcessHeap(), 0, lenW*sizeof(WCHAR)); + MultiByteToWideChar(cp, 0, str, count, strW, lenW); + if(plenW) *plenW = lenW; + if(pCP) *pCP = cp; + return strW; +} + + static BOOL FASTCALL MetricsCharConvert(WCHAR w, UCHAR *b) { @@ -347,8 +414,34 @@ GetCharWidth32A( LPINT lpBuffer ) { - /* FIXME what to do with iFirstChar and iLastChar ??? */ - return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); + INT i, wlen, count = (INT)(iLastChar - iFirstChar + 1); + LPSTR str; + LPWSTR wstr; + BOOL ret = TRUE; + + if(count <= 0) return FALSE; + + str = HeapAlloc(GetProcessHeap(), 0, count); + for(i = 0; i < count; i++) + str[i] = (BYTE)(iFirstChar + i); + + wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL); + + for(i = 0; i < wlen; i++) + { + /* FIXME should be NtGdiGetCharWidthW */ + if(!NtGdiGetCharWidth32(hdc, wstr[i], wstr[i], lpBuffer)) + { + ret = FALSE; + break; + } + lpBuffer++; + } + + HeapFree(GetProcessHeap(), 0, str); + HeapFree(GetProcessHeap(), 0, wstr); + + return ret; } @@ -364,6 +457,7 @@ GetCharWidthW ( LPINT lpBuffer ) { + /* FIXME should be NtGdiGetCharWidthW */ return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer ); }