Commit f20ce3b8 authored by Rein Klazes's avatar Rein Klazes Committed by Alexandre Julliard

Fix MultiByteToWideChar and WideCharToMultiByte when called with code

page CP_SYMBOL. Remove the symbol font from the code page table, so it is not reported as a valid/supported/installed code page. Remove workarounds for the badly behaved MultiByteToWideChar and co. in a few places.
parent c6601176
......@@ -124,15 +124,9 @@ MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
TRACE("cp == %d\n", cp);
if(cp != CP_SYMBOL) {
len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
ascii = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
} else {
len = count;
ascii = HeapAlloc(GetProcessHeap(), 0, len);
for(i = 0; i < count; i++) ascii[i] = (BYTE)(str[i] & 0xff);
}
len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
ascii = HeapAlloc(GetProcessHeap(), 0, len);
WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
TRACE("mapped %s -> %s\n", debugstr_wn(str, count), debugstr_an(ascii, len));
......
......@@ -1190,8 +1190,6 @@ UINT WINAPI GetOEMCP(void)
BOOL WINAPI IsValidCodePage( UINT codepage )
{
switch(codepage) {
case CP_SYMBOL:
return FALSE;
case CP_UTF7:
case CP_UTF8:
return TRUE;
......@@ -1425,6 +1423,14 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
switch(page)
{
case CP_SYMBOL:
if( flags)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
ret = wine_cpsymbol_mbstowcs( src, srclen, dst, dstlen );
break;
case CP_UTF7:
FIXME("UTF-7 not supported\n");
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
......@@ -1503,6 +1509,14 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
switch(page)
{
case CP_SYMBOL:
if( flags || defchar || used)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
ret = wine_cpsymbol_wcstombs( src, srclen, dst, dstlen );
break;
case CP_UTF7:
FIXME("UTF-7 not supported\n");
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
......@@ -1530,9 +1544,13 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
break;
}
if (ret == -1)
if (ret < 0)
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
switch(ret)
{
case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
}
ret = 0;
}
TRACE("cp %d %s -> %s\n", page, debugstr_w(src), debugstr_a(dst));
......
......@@ -75,8 +75,10 @@ extern int wine_cp_mbstowcs( const union cptable *table, int flags,
extern int wine_cp_wcstombs( const union cptable *table, int flags,
const WCHAR *src, int srclen,
char *dst, int dstlen, const char *defchar, int *used );
extern int wine_utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
extern int wine_cpsymbol_mbstowcs( const char *src, int srclen, WCHAR *dst, int dstlen );
extern int wine_cpsymbol_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
extern int wine_utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
extern int wine_utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
extern int wine_compare_string( int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2 );
extern int wine_get_sortkey( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
......
......@@ -8,7 +8,6 @@ EXTRADEFS = -D__WINESRC__ -DNO_LIBWINE_PORT -DWINE_UNICODE_API=""
CODEPAGES = \
037 \
042 \
424 \
437 \
500 \
......
......@@ -38,7 +38,6 @@ $DEF_CHAR = ord '?';
@allfiles =
(
[ 37, "VENDORS/MICSFT/EBCDIC/CP037.TXT", "IBM EBCDIC US Canada" ],
[ 42, "VENDORS/ADOBE/symbol.txt", "Symbol" ],
[ 424, "VENDORS/MISC/CP424.TXT", "IBM EBCDIC Hebrew" ],
[ 437, "VENDORS/MICSFT/PC/CP437.TXT", "OEM United States" ],
[ 500, "VENDORS/MICSFT/EBCDIC/CP500.TXT", "IBM EBCDIC International" ],
......@@ -397,34 +396,6 @@ sub READ_FILE
################################################################
# parse the symbol.txt file, since its syntax is different from the other ones
sub READ_SYMBOL_FILE
{
my $name = shift;
open INPUT,$name or die "Cannot open $name";
@cp2uni = ();
@lead_bytes = ();
@uni2cp = ();
while (<INPUT>)
{
next if /^\#/; # skip comments
next if /^$/; # skip empty lines
next if /\x1a/; # skip ^Z
if (/^([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+(\#.*)?/)
{
$uni = hex $1;
$cp = hex $2;
$cp2uni[$cp] = $uni unless defined($cp2uni[$cp]);
$uni2cp[$uni] = $cp unless defined($uni2cp[$uni]);
next;
}
die "$name: Unrecognized line $_\n";
}
}
################################################################
# build EUC-JP table from the JIS 0208 file
# FIXME: for proper EUC-JP we should probably read JIS 0212 too
# but this would require 3-byte DBCS characters
......@@ -1165,8 +1136,7 @@ sub HANDLE_FILE
my ($codepage,$filename,$comment) = @_;
# symbol codepage file is special
if ($codepage == 42) { READ_SYMBOL_FILE($MAPPREFIX . $filename); }
elsif ($codepage == 20932) { READ_JIS0208_FILE($MAPPREFIX . $filename); }
if ($codepage == 20932) { READ_JIS0208_FILE($MAPPREFIX . $filename); }
else { READ_FILE($MAPPREFIX . $filename); }
# hack: 0x00a5 must map to backslash in Shift-JIS
......
......@@ -25,7 +25,6 @@
/* Everything below this line is generated automatically by cpmap.pl */
/* ### cpmap begin ### */
extern union cptable cptable_037;
extern union cptable cptable_042;
extern union cptable cptable_424;
extern union cptable cptable_437;
extern union cptable cptable_500;
......@@ -85,10 +84,9 @@ extern union cptable cptable_28604;
extern union cptable cptable_28605;
extern union cptable cptable_28606;
static const union cptable * const cptables[60] =
static const union cptable * const cptables[59] =
{
&cptable_037,
&cptable_042,
&cptable_424,
&cptable_437,
&cptable_500,
......
......@@ -277,3 +277,22 @@ int wine_cp_mbstowcs( const union cptable *table, int flags,
return mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen );
}
}
/* CP_SYMBOL implementation */
/* return -1 on dst buffer overflow */
int wine_cpsymbol_mbstowcs( const char *src, int srclen, WCHAR *dst, int dstlen)
{
int len, i;
if( dstlen == 0) return srclen;
len = dstlen > srclen ? srclen : dstlen;
for( i = 0; i < len; i++)
{
unsigned char c = src [ i ];
if( c < 0x20 )
dst[i] = c;
else
dst[i] = c + 0xf000;
}
if( srclen > len) return -1;
return len;
}
......@@ -454,3 +454,24 @@ int wine_cp_wcstombs( const union cptable *table, int flags,
return wcstombs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
}
}
/* CP_SYMBOL implementation */
/* return -1 on dst buffer overflow, -2 on invalid character */
int wine_cpsymbol_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen)
{
int len, i;
if( dstlen == 0) return srclen;
len = dstlen > srclen ? srclen : dstlen;
for( i = 0; i < len; i++)
{
WCHAR w = src [ i ];
if( w < 0x20 )
dst[i] = w;
else if( w >= 0xf020 && w < 0xf100)
dst[i] = w - 0xf000;
else
return -2;
}
if( srclen > len) return -1;
return len;
}
......@@ -17,6 +17,8 @@ EXPORTS
wine_cp_get_table
wine_cp_mbstowcs
wine_cp_wcstombs
wine_cpsymbol_mbstowcs
wine_cpsymbol_wcstombs
wine_fold_string
wine_get_sortkey
wine_utf8_mbstowcs
......
......@@ -1992,7 +1992,7 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
DWORD dwFlags)
{
WCHAR *lpStringW;
INT uCountW, i;
INT uCountW;
GCP_RESULTSW resultsW;
DWORD ret;
UINT font_cp;
......@@ -2010,12 +2010,8 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
if(lpResults->lpOutString) {
if(font_cp != CP_SYMBOL)
WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
lpResults->lpOutString, uCount, NULL, NULL );
else
for(i = 0; i < uCount; i++)
lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
lpResults->lpOutString, uCount, NULL, NULL );
}
HeapFree(GetProcessHeap(), 0, lpStringW);
......
......@@ -43,14 +43,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(text);
* 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 (NB, this may be CP_SYMBOL so watch
* out). The caller should free the returned LPWSTR from the process
* 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)
{
UINT cp = CP_ACP;
INT lenW, i;
INT lenW;
LPWSTR strW;
CHARSETINFO csi;
int charset = GetTextCharset(hdc);
......@@ -94,15 +94,9 @@ LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
TRACE("cp == %d\n", cp);
if(count == -1) count = strlen(str);
if(cp != CP_SYMBOL) {
lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
MultiByteToWideChar(cp, 0, str, count, strW, lenW);
} else {
lenW = count;
strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
}
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';
TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
if(plenW) *plenW = lenW;
......
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