wine font 加載過程

本文分析wine 加載font的過程。
第一步,update_font_info();
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);
    }
}
第二步,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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章