Commit 1c846e70 authored by Byeongsik Jeon's avatar Byeongsik Jeon Committed by Alexandre Julliard

gdi32: Fix the GdiGetCodePage() support ANSI_CHARSET font associated charset.

parent f13394f7
......@@ -590,11 +590,66 @@ HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
return CreateFontIndirectW( &logfont );
}
#define ASSOC_CHARSET_OEM 1
#define ASSOC_CHARSET_ANSI 2
#define ASSOC_CHARSET_SYMBOL 4
static DWORD get_associated_charset_info(void)
{
static DWORD associated_charset = -1;
if (associated_charset == -1)
{
static const WCHAR assoc_charset_reg_keyW[] = {'S','y','s','t','e','m','\\',
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
'C','o','n','t','r','o','l','\\','F','o','n','t','A','s','s','o','c','\\',
'A','s','s','o','c','i','a','t','e','d',' ','C','h','a','r','s','e','t','\0'};
static const WCHAR ansiW[] = {'A','N','S','I','(','0','0',')','\0'};
static const WCHAR oemW[] = {'O','E','M','(','F','F',')','\0'};
static const WCHAR symbolW[] = {'S','Y','M','B','O','L','(','0','2',')','\0'};
static const WCHAR yesW[] = {'Y','E','S','\0'};
HKEY hkey;
WCHAR dataW[32];
DWORD type, data_len;
associated_charset = 0;
if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
assoc_charset_reg_keyW, &hkey) != ERROR_SUCCESS)
return 0;
data_len = sizeof(dataW);
if (!RegQueryValueExW(hkey, ansiW, NULL, &type, (LPBYTE)dataW, &data_len) &&
type == REG_SZ && !strcmpiW(dataW, yesW))
associated_charset |= ASSOC_CHARSET_ANSI;
data_len = sizeof(dataW);
if (!RegQueryValueExW(hkey, oemW, NULL, &type, (LPBYTE)dataW, &data_len) &&
type == REG_SZ && !strcmpiW(dataW, yesW))
associated_charset |= ASSOC_CHARSET_OEM;
data_len = sizeof(dataW);
if (!RegQueryValueExW(hkey, symbolW, NULL, &type, (LPBYTE)dataW, &data_len) &&
type == REG_SZ && !strcmpiW(dataW, yesW))
associated_charset |= ASSOC_CHARSET_SYMBOL;
RegCloseKey(hkey);
TRACE("associated_charset = %d\n", associated_charset);
}
return associated_charset;
}
static void update_font_code_page( DC *dc )
{
CHARSETINFO csi;
int charset = GetTextCharsetInfo( dc->hSelf, NULL, 0 );
if (charset == ANSI_CHARSET &&
get_associated_charset_info() & ASSOC_CHARSET_ANSI)
charset = DEFAULT_CHARSET;
/* Hmm, nicely designed api this one! */
if (TranslateCharsetInfo( ULongToPtr(charset), &csi, TCI_SRCCHARSET) )
dc->font_code_page = csi.ciACP;
......
......@@ -3505,6 +3505,46 @@ static void set_value_key(HKEY hkey, const char *name, const char *value)
RegDeleteValueA(hkey, name);
}
static void update_font_association_info(UINT current_ansi_codepage)
{
static const char *font_assoc_reg_key = "System\\CurrentControlSet\\Control\\FontAssoc";
static const char *assoc_charset_subkey = "Associated Charset";
if (is_dbcs_ansi_cp(current_ansi_codepage))
{
HKEY hkey;
if (RegCreateKeyA(HKEY_LOCAL_MACHINE, font_assoc_reg_key, &hkey) == ERROR_SUCCESS)
{
HKEY hsubkey;
if (RegCreateKeyA(hkey, assoc_charset_subkey, &hsubkey) == ERROR_SUCCESS)
{
switch (current_ansi_codepage)
{
case 932:
set_value_key(hsubkey, "ANSI(00)", "NO");
set_value_key(hsubkey, "OEM(FF)", "NO");
set_value_key(hsubkey, "SYMBOL(02)", "NO");
break;
case 936:
case 949:
case 950:
set_value_key(hsubkey, "ANSI(00)", "YES");
set_value_key(hsubkey, "OEM(FF)", "YES");
set_value_key(hsubkey, "SYMBOL(02)", "NO");
break;
}
RegCloseKey(hsubkey);
}
/* TODO: Associated DefaultFonts */
RegCloseKey(hkey);
}
}
else
RegDeleteTreeA(HKEY_LOCAL_MACHINE, font_assoc_reg_key);
}
static void update_font_info(void)
{
static const WCHAR logpixels[] = { 'L','o','g','P','i','x','e','l','s',0 };
......@@ -3538,6 +3578,7 @@ static void update_font_info(void)
if (is_dbcs_ansi_cp(ansi_cp))
use_default_fallback = TRUE;
buf[0] = 0;
len = sizeof(buf);
if (RegQueryValueExA(hkey, "Codepages", 0, &type, (BYTE *)buf, &len) == ERROR_SUCCESS && type == REG_SZ)
{
......@@ -3615,6 +3656,11 @@ static void update_font_info(void)
}
if (!done)
FIXME("there is no font defaults for codepages %u,%u\n", ansi_cp, oem_cp);
/* update locale dependent font association info in registry.
update only when codepages changed, not logpixels. */
if (strcmp(buf, cpbuf) != 0)
update_font_association_info(ansi_cp);
}
static BOOL init_freetype(void)
......
......@@ -2083,6 +2083,90 @@ static void test_font_charset(void)
skip("Symbol or Wingdings is not installed\n");
}
static void test_GdiGetCodePage(void)
{
static const struct _matching_data
{
UINT current_codepage;
LPCSTR lfFaceName;
UCHAR lfCharSet;
UINT expected_codepage;
} matching_data[] = {
{1251, "Arial", ANSI_CHARSET, 1252},
{1251, "Tahoma", ANSI_CHARSET, 1252},
{1252, "Arial", ANSI_CHARSET, 1252},
{1252, "Tahoma", ANSI_CHARSET, 1252},
{1253, "Arial", ANSI_CHARSET, 1252},
{1253, "Tahoma", ANSI_CHARSET, 1252},
{ 932, "Arial", ANSI_CHARSET, 1252}, /* Japanese Windows returns 1252, not 932 */
{ 932, "Tahoma", ANSI_CHARSET, 1252},
{ 932, "MS UI Gothic", ANSI_CHARSET, 1252},
{ 936, "Arial", ANSI_CHARSET, 936},
{ 936, "Tahoma", ANSI_CHARSET, 936},
{ 936, "Simsun", ANSI_CHARSET, 936},
{ 949, "Arial", ANSI_CHARSET, 949},
{ 949, "Tahoma", ANSI_CHARSET, 949},
{ 949, "Gulim", ANSI_CHARSET, 949},
{ 950, "Arial", ANSI_CHARSET, 950},
{ 950, "Tahoma", ANSI_CHARSET, 950},
{ 950, "PMingLiU", ANSI_CHARSET, 950},
};
HDC hdc;
LOGFONT lf;
HFONT hfont;
UINT charset, acp;
DWORD codepage;
int i;
if (!pGdiGetCodePage)
{
skip("GdiGetCodePage not available on this platform\n");
return;
}
acp = GetACP();
for (i = 0; i < sizeof(matching_data) / sizeof(struct _matching_data); i++)
{
/* only test data matched current locale codepage */
if (matching_data[i].current_codepage != acp)
continue;
if (!is_font_installed(matching_data[i].lfFaceName))
{
skip("%s is not installed\n", matching_data[i].lfFaceName);
continue;
}
hdc = GetDC(0);
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -16;
lf.lfCharSet = matching_data[i].lfCharSet;
lstrcpyA(lf.lfFaceName, matching_data[i].lfFaceName);
hfont = CreateFontIndirectA(&lf);
ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError());
hfont = SelectObject(hdc, hfont);
charset = GetTextCharset(hdc);
codepage = pGdiGetCodePage(hdc);
trace("acp=%d, lfFaceName=%s, lfCharSet=%d, GetTextCharset=%d, GdiGetCodePage=%d, expected codepage=%d\n",
acp, lf.lfFaceName, lf.lfCharSet, charset, codepage, matching_data[i].expected_codepage);
ok(codepage == matching_data[i].expected_codepage,
"GdiGetCodePage should have returned %d, got %d\n", matching_data[i].expected_codepage, codepage);
hfont = SelectObject(hdc, hfont);
DeleteObject(hfont);
ReleaseDC(NULL, hdc);
}
}
static void test_GetFontUnicodeRanges(void)
{
LOGFONTA lf;
......@@ -4902,6 +4986,7 @@ START_TEST(font)
test_GetOutlineTextMetrics();
test_SetTextJustification();
test_font_charset();
test_GdiGetCodePage();
test_GetFontUnicodeRanges();
test_nonexistent_font();
test_orientation();
......
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