gdi32: Support UTF-8 codepage in TranslateCharsetInfo().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52847
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-04-22 12:40:48 +02:00
parent cc83e85263
commit 7500fc1ce9
3 changed files with 156 additions and 103 deletions

View file

@ -965,7 +965,7 @@ static void test_bitmap_font_metrics(void)
SetLastError(0xdeadbeef);
ret = GetTextCharset(hdc);
if (is_CJK() && lf.lfCharSet == ANSI_CHARSET)
if ((is_CJK() || expected_cs == 254) && lf.lfCharSet == ANSI_CHARSET)
ok(ret == ANSI_CHARSET, "got charset %d, expected ANSI_CHARSETd\n", ret);
else
ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs);
@ -2569,6 +2569,98 @@ static BOOL get_glyph_indices(INT charset, UINT code_page, WORD *idx, UINT count
return TRUE;
}
static void test_TranslateCharsetInfo(void)
{
static CHARSETINFO tests[] =
{
{ ANSI_CHARSET, 1252, { {0}, { FS_LATIN1 }}},
{ EASTEUROPE_CHARSET, 1250, { {0}, { FS_LATIN2 }}},
{ RUSSIAN_CHARSET, 1251, { {0}, { FS_CYRILLIC }}},
{ GREEK_CHARSET, 1253, { {0}, { FS_GREEK }}},
{ TURKISH_CHARSET, 1254, { {0}, { FS_TURKISH }}},
{ HEBREW_CHARSET, 1255, { {0}, { FS_HEBREW }}},
{ ARABIC_CHARSET, 1256, { {0}, { FS_ARABIC }}},
{ BALTIC_CHARSET, 1257, { {0}, { FS_BALTIC }}},
{ VIETNAMESE_CHARSET, 1258, { {0}, { FS_VIETNAMESE }}},
{ THAI_CHARSET, 874, { {0}, { FS_THAI }}},
{ SHIFTJIS_CHARSET, 932, { {0}, { FS_JISJAPAN }}},
{ GB2312_CHARSET, 936, { {0}, { FS_CHINESESIMP }}},
{ HANGEUL_CHARSET, 949, { {0}, { FS_WANSUNG }}},
{ CHINESEBIG5_CHARSET, 950, { {0}, { FS_CHINESETRAD }}},
{ JOHAB_CHARSET, 1361, { {0}, { FS_JOHAB }}},
{ 254, CP_UTF8, { {0}, { 0x04000000 }}},
{ SYMBOL_CHARSET, CP_SYMBOL, { {0}, { FS_SYMBOL }}}
};
CHARSETINFO csi;
DWORD i, j;
BOOL ret;
/* try all codepages */
for (i = 0; i < 65536; i++)
{
memset( &csi, 0xcc, sizeof(csi) );
ret = TranslateCharsetInfo( ULongToPtr(i), &csi, TCI_SRCCODEPAGE );
if (ret)
{
for (j = 0; j < ARRAY_SIZE(tests); j++)
{
if (tests[j].ciACP != i) continue;
ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
"%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
break;
}
ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
}
else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
}
/* try all charsets */
for (i = 0; i < 256; i++)
{
memset( &csi, 0xcc, sizeof(csi) );
ret = TranslateCharsetInfo( ULongToPtr(i), &csi, TCI_SRCCHARSET );
if (ret)
{
for (j = 0; j < ARRAY_SIZE(tests); j++)
{
if (tests[j].ciCharset != i) continue;
ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
"%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
break;
}
ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
}
else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
}
/* try all fontsigs */
for (i = 0; i < 64; i++)
{
DWORD csb[2] = { 0, 0 };
csb[i / 32] = 1 << (i % 32);
memset( &csi, 0xcc, sizeof(csi) );
ret = TranslateCharsetInfo( csb, &csi, TCI_SRCFONTSIG );
if (ret)
{
for (j = 0; j < ARRAY_SIZE(tests); j++)
{
if (tests[j].fs.fsCsb[0] != csb[0]) continue;
ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
"%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
break;
}
ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
}
else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
}
}
static void test_font_charset(void)
{
static struct charset_data
@ -7685,6 +7777,7 @@ START_TEST(font)
test_GetOutlineTextMetrics();
test_GetOutlineTextMetrics_subst();
test_SetTextJustification();
test_TranslateCharsetInfo();
test_font_charset();
test_GdiGetCodePage();
test_GetFontUnicodeRanges();

View file

@ -2728,44 +2728,25 @@ done:
return FALSE;
}
static const CHARSETINFO charset_info[] = {
/* ANSI */
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
{ EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
{ RUSSIAN_CHARSET, 1251, {{0,0,0,0},{FS_CYRILLIC,0}} },
{ GREEK_CHARSET, 1253, {{0,0,0,0},{FS_GREEK,0}} },
{ TURKISH_CHARSET, 1254, {{0,0,0,0},{FS_TURKISH,0}} },
{ HEBREW_CHARSET, 1255, {{0,0,0,0},{FS_HEBREW,0}} },
{ ARABIC_CHARSET, 1256, {{0,0,0,0},{FS_ARABIC,0}} },
{ BALTIC_CHARSET, 1257, {{0,0,0,0},{FS_BALTIC,0}} },
{ VIETNAMESE_CHARSET, 1258, {{0,0,0,0},{FS_VIETNAMESE,0}} },
/* reserved by ANSI */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* ANSI and OEM */
{ THAI_CHARSET, 874, {{0,0,0,0},{FS_THAI,0}} },
{ SHIFTJIS_CHARSET, 932, {{0,0,0,0},{FS_JISJAPAN,0}} },
{ GB2312_CHARSET, 936, {{0,0,0,0},{FS_CHINESESIMP,0}} },
{ HANGEUL_CHARSET, 949, {{0,0,0,0},{FS_WANSUNG,0}} },
{ CHINESEBIG5_CHARSET, 950, {{0,0,0,0},{FS_CHINESETRAD,0}} },
{ JOHAB_CHARSET, 1361, {{0,0,0,0},{FS_JOHAB,0}} },
/* reserved for alternate ANSI and OEM */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* reserved for system */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
static const CHARSETINFO charset_info[] =
{
{ ANSI_CHARSET, 1252, { {0}, { FS_LATIN1 }}},
{ EASTEUROPE_CHARSET, 1250, { {0}, { FS_LATIN2 }}},
{ RUSSIAN_CHARSET, 1251, { {0}, { FS_CYRILLIC }}},
{ GREEK_CHARSET, 1253, { {0}, { FS_GREEK }}},
{ TURKISH_CHARSET, 1254, { {0}, { FS_TURKISH }}},
{ HEBREW_CHARSET, 1255, { {0}, { FS_HEBREW }}},
{ ARABIC_CHARSET, 1256, { {0}, { FS_ARABIC }}},
{ BALTIC_CHARSET, 1257, { {0}, { FS_BALTIC }}},
{ VIETNAMESE_CHARSET, 1258, { {0}, { FS_VIETNAMESE }}},
{ THAI_CHARSET, 874, { {0}, { FS_THAI }}},
{ SHIFTJIS_CHARSET, 932, { {0}, { FS_JISJAPAN }}},
{ GB2312_CHARSET, 936, { {0}, { FS_CHINESESIMP }}},
{ HANGEUL_CHARSET, 949, { {0}, { FS_WANSUNG }}},
{ CHINESEBIG5_CHARSET, 950, { {0}, { FS_CHINESETRAD }}},
{ JOHAB_CHARSET, 1361, { {0}, { FS_JOHAB }}},
{ 254, CP_UTF8, { {0}, { 0x04000000 }}},
{ SYMBOL_CHARSET, CP_SYMBOL, { {0}, { FS_SYMBOL }}}
};
/***********************************************************************
@ -2785,27 +2766,26 @@ static const CHARSETINFO charset_info[] = {
*/
BOOL WINAPI TranslateCharsetInfo( DWORD *src, CHARSETINFO *cs, DWORD flags )
{
int index = 0;
unsigned int i;
switch (flags)
{
case TCI_SRCFONTSIG:
while (index < ARRAY_SIZE(charset_info) && !(*src>>index & 0x0001)) index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (charset_info[i].fs.fsCsb[0] & src[0]) goto found;
return FALSE;
case TCI_SRCCODEPAGE:
while (index < ARRAY_SIZE(charset_info) && PtrToUlong(src) != charset_info[index].ciACP)
index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (PtrToUlong(src) == charset_info[i].ciACP) goto found;
return FALSE;
case TCI_SRCCHARSET:
while (index < ARRAY_SIZE(charset_info) &&
PtrToUlong(src) != charset_info[index].ciCharset)
index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (PtrToUlong(src) == charset_info[i].ciCharset) goto found;
return FALSE;
default:
return FALSE;
}
if (index >= ARRAY_SIZE(charset_info) || charset_info[index].ciCharset == DEFAULT_CHARSET) return FALSE;
*cs = charset_info[index];
found:
*cs = charset_info[i];
return TRUE;
}

View file

@ -288,44 +288,25 @@ typedef struct
} FONTOBJ;
/* for translate_charset_info */
static const CHARSETINFO charset_info[] = {
/* ANSI */
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
{ EASTEUROPE_CHARSET, 1250, {{0,0,0,0},{FS_LATIN2,0}} },
{ RUSSIAN_CHARSET, 1251, {{0,0,0,0},{FS_CYRILLIC,0}} },
{ GREEK_CHARSET, 1253, {{0,0,0,0},{FS_GREEK,0}} },
{ TURKISH_CHARSET, 1254, {{0,0,0,0},{FS_TURKISH,0}} },
{ HEBREW_CHARSET, 1255, {{0,0,0,0},{FS_HEBREW,0}} },
{ ARABIC_CHARSET, 1256, {{0,0,0,0},{FS_ARABIC,0}} },
{ BALTIC_CHARSET, 1257, {{0,0,0,0},{FS_BALTIC,0}} },
{ VIETNAMESE_CHARSET, 1258, {{0,0,0,0},{FS_VIETNAMESE,0}} },
/* reserved by ANSI */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* ANSI and OEM */
{ THAI_CHARSET, 874, {{0,0,0,0},{FS_THAI,0}} },
{ SHIFTJIS_CHARSET, 932, {{0,0,0,0},{FS_JISJAPAN,0}} },
{ GB2312_CHARSET, 936, {{0,0,0,0},{FS_CHINESESIMP,0}} },
{ HANGEUL_CHARSET, 949, {{0,0,0,0},{FS_WANSUNG,0}} },
{ CHINESEBIG5_CHARSET, 950, {{0,0,0,0},{FS_CHINESETRAD,0}} },
{ JOHAB_CHARSET, 1361, {{0,0,0,0},{FS_JOHAB,0}} },
/* reserved for alternate ANSI and OEM */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
/* reserved for system */
{ DEFAULT_CHARSET, 0, {{0,0,0,0},{FS_LATIN1,0}} },
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
static const CHARSETINFO charset_info[] =
{
{ ANSI_CHARSET, 1252, { {0}, { FS_LATIN1 }}},
{ EASTEUROPE_CHARSET, 1250, { {0}, { FS_LATIN2 }}},
{ RUSSIAN_CHARSET, 1251, { {0}, { FS_CYRILLIC }}},
{ GREEK_CHARSET, 1253, { {0}, { FS_GREEK }}},
{ TURKISH_CHARSET, 1254, { {0}, { FS_TURKISH }}},
{ HEBREW_CHARSET, 1255, { {0}, { FS_HEBREW }}},
{ ARABIC_CHARSET, 1256, { {0}, { FS_ARABIC }}},
{ BALTIC_CHARSET, 1257, { {0}, { FS_BALTIC }}},
{ VIETNAMESE_CHARSET, 1258, { {0}, { FS_VIETNAMESE }}},
{ THAI_CHARSET, 874, { {0}, { FS_THAI }}},
{ SHIFTJIS_CHARSET, 932, { {0}, { FS_JISJAPAN }}},
{ GB2312_CHARSET, 936, { {0}, { FS_CHINESESIMP }}},
{ HANGEUL_CHARSET, 949, { {0}, { FS_WANSUNG }}},
{ CHINESEBIG5_CHARSET, 950, { {0}, { FS_CHINESETRAD }}},
{ JOHAB_CHARSET, 1361, { {0}, { FS_JOHAB }}},
{ 254, CP_UTF8, { {0}, { 0x04000000 }}},
{ SYMBOL_CHARSET, CP_SYMBOL, { {0}, { FS_SYMBOL }}}
};
static const char * const default_serif_list[3] =
@ -1695,28 +1676,27 @@ static void load_system_links(void)
/* see TranslateCharsetInfo */
BOOL translate_charset_info( DWORD *src, CHARSETINFO *cs, DWORD flags )
{
int index = 0;
unsigned int i;
switch (flags)
{
case TCI_SRCFONTSIG:
while (index < ARRAY_SIZE(charset_info) && !(*src>>index & 0x0001)) index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (charset_info[i].fs.fsCsb[0] & src[0]) goto found;
return FALSE;
case TCI_SRCCODEPAGE:
while (index < ARRAY_SIZE(charset_info) && PtrToUlong(src) != charset_info[index].ciACP)
index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (PtrToUlong(src) == charset_info[i].ciACP) goto found;
return FALSE;
case TCI_SRCCHARSET:
while (index < ARRAY_SIZE(charset_info) &&
PtrToUlong(src) != charset_info[index].ciCharset)
index++;
break;
for (i = 0; i < ARRAY_SIZE(charset_info); i++)
if (PtrToUlong(src) == charset_info[i].ciCharset) goto found;
return FALSE;
default:
return FALSE;
}
if (index >= ARRAY_SIZE(charset_info) || charset_info[index].ciCharset == DEFAULT_CHARSET) return FALSE;
*cs = charset_info[index];
found:
*cs = charset_info[i];
return TRUE;
}