static void update_font_info(void)
{
static const WCHAR logpixels[] = { 'L','o','g','P','i','x','e','l','s',0 };
char buf[40], cpbuf[40];
DWORD len, type;
HKEY hkey = 0;
UINT i, ansi_cp = 0, oem_cp = 0;
DWORD screen_dpi = 96, font_dpi = 0;
BOOL done = FALSE;
if (RegOpenKeyA(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Hardware Profiles\\Current\\Software\\Fonts",
&hkey) == ERROR_SUCCESS)
{
reg_load_dword(hkey, logpixels, &screen_dpi);
RegCloseKey(hkey);
}
if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL) != ERROR_SUCCESS)
return;
reg_load_dword(hkey, logpixels, &font_dpi);
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER|LOCALE_NOUSEROVERRIDE,
(WCHAR *)&ansi_cp, sizeof(ansi_cp)/sizeof(WCHAR));
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTCODEPAGE|LOCALE_RETURN_NUMBER|LOCALE_NOUSEROVERRIDE,
(WCHAR *)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR));
sprintf( cpbuf, "%u,%u", ansi_cp, oem_cp );
/* Setup Default_Fallback usage for DBCS ANSI codepages */
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)
{
if (!strcmp( buf, cpbuf ) && screen_dpi == font_dpi) /* already set correctly */
{
RegCloseKey(hkey);
return;
}
TRACE("updating registry, codepages/logpixels changed %s/%u -> %u,%u/%u\n",
buf, font_dpi, ansi_cp, oem_cp, screen_dpi);
}
else TRACE("updating registry, codepages/logpixels changed none -> %u,%u/%u\n",
ansi_cp, oem_cp, screen_dpi);
RegSetValueExA(hkey, "Codepages", 0, REG_SZ, (const BYTE *)cpbuf, strlen(cpbuf)+1);
RegSetValueExW(hkey, logpixels, 0, REG_DWORD, (const BYTE *)&screen_dpi, sizeof(screen_dpi));
RegCloseKey(hkey);
for (i = 0; i < sizeof(nls_update_font_list)/sizeof(nls_update_font_list[0]); i++)
{
HKEY hkey;
if (nls_update_font_list[i].ansi_cp == ansi_cp &&
nls_update_font_list[i].oem_cp == oem_cp)
{
hkey = create_config_fonts_registry_key();
RegSetValueExA(hkey, "OEMFONT.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].oem, strlen(nls_update_font_list[i].oem)+1);
RegSetValueExA(hkey, "FIXEDFON.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].fixed, strlen(nls_update_font_list[i].fixed)+1);
RegSetValueExA(hkey, "FONTS.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].system, strlen(nls_update_font_list[i].system)+1);
RegCloseKey(hkey);
hkey = create_fonts_NT_registry_key();
add_font_list(hkey, &nls_update_font_list[i], screen_dpi);
RegCloseKey(hkey);
hkey = create_fonts_9x_registry_key();
add_font_list(hkey, &nls_update_font_list[i], screen_dpi);
RegCloseKey(hkey);
if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes", &hkey ))
{
RegSetValueExA(hkey, "MS Shell Dlg", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].shelldlg,
strlen(nls_update_font_list[i].shelldlg)+1);
RegSetValueExA(hkey, "Tms Rmn", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].tmsrmn,
strlen(nls_update_font_list[i].tmsrmn)+1);
set_value_key(hkey, "Fixedsys,0", nls_update_font_list[i].fixed_0);
set_value_key(hkey, "System,0", nls_update_font_list[i].system_0);
set_value_key(hkey, "Courier,0", nls_update_font_list[i].courier_0);
set_value_key(hkey, "MS Serif,0", nls_update_font_list[i].serif_0);
set_value_key(hkey, "Small Fonts,0", nls_update_font_list[i].small_0);
set_value_key(hkey, "MS Sans Serif,0", nls_update_font_list[i].sserif_0);
set_value_key(hkey, "Helv,0", nls_update_font_list[i].helv_0);
set_value_key(hkey, "Tms Rmn,0", nls_update_font_list[i].tmsrmn_0);
set_value_key(hkey, nls_update_font_list[i].arial_0.from, nls_update_font_list[i].arial_0.to);
set_value_key(hkey, nls_update_font_list[i].courier_new_0.from, nls_update_font_list[i].courier_new_0.to);
set_value_key(hkey, nls_update_font_list[i].times_new_roman_0.from, nls_update_font_list[i].times_new_roman_0.to);
RegCloseKey(hkey);
}
done = TRUE;
}
else
{
/* Delete the FontSubstitutes from other locales */
if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes", &hkey ))
{
set_value_key(hkey, nls_update_font_list[i].arial_0.from, NULL);
set_value_key(hkey, nls_update_font_list[i].courier_new_0.from, NULL);
set_value_key(hkey, nls_update_font_list[i].times_new_roman_0.from, NULL);
RegCloseKey(hkey);
}
}
}
if (!done)
FIXME("there is no font defaults for codepages %u,%u\n", ansi_cp, oem_cp);
/* update locale dependent font association info and font system link info in registry.
update only when codepages changed, not logpixels. */
if (strcmp(buf, cpbuf) != 0)
{
update_font_association_info(ansi_cp);
update_font_system_link_info(ansi_cp);
}
}
wine font 加載過程
本文分析wine 加載font的過程。
第一步,update_font_info();
第二步,init_freetype(),加載"libfreetype.so.6"
第三步,init_fontconfig(),加載"libfontconfig.so.1"
第四步,打開[HKEY_CURRENT_USER\\Software\\Wine\\Fonts]下的字體設置
查詢AntialiasFakeBoldOrItalic 即反鋸齒,粗體或斜體,設置反鋸齒屬性
第五步,加載字體
1、如果[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\Cache] 是新創建的,重新根據Windows\\Fonts 目錄來加載所有字體否則根據Cache 鍵值進行加載
1) 刪除[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\External Fonts] 鍵值,並將在[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts]或[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts]的對應信息刪掉
2)加載系統字體,即註冊表【HKEY_CUDRDRENT_CONFIG\\Software\\Fonts】
3) 加載Windows\\Fonts\\下的字體,wine\fonts\ 下字體,[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts]或[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts] 記錄的字體
4)加載 【HKEY_CURRENT_USER\\Software\\Wine\\Fonts】的字體
2、如果[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\External Fonts] 鍵值已經存在,則根據這裏面進行加載。
3、加載[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes]的字體
4、加載[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\Replacements]的字體
第六步,根據已加載的字體更新以下注冊表鍵值
[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts]的字體
[HKEY_LOCAL_MECHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts]的字體
[HKEY_CURRENT_USER\\Software\\Wine\\Fonts\\External Fonts]的字體
第七步,初始化 SystemLink
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.