为什么字符“0x62A”用“Calibri”字体打印,但字符“0x660E”不是?

时间:2012-06-29 19:04:04

标签: c++ winapi fonts

Calibri字体既没有其中一个字符,0x062A0x660E,但第一个字符使用其他字体打印。但是,字符0x660E显示为无效的字符代码。为什么TextOut()不能替换字体来打印最后一个字符,与字符代码0x062A相同?

如果我将Calibri字体替换为Arial,则结果相同。

编辑:我也想提醒你注意这句话,可以在这里找到http://msdn.microsoft.com/en-us/goglobal/bb688134.aspx:“Windows核心字体(Times New Roman,Courier New,Arial,Microsoft Sans Serif,and Tahoma)包含拉丁语,希伯来语,阿拉伯语,希腊语和西里尔语脚本,但不包含东亚脚本字符。它们链接到那些字体。“我已经尝试了所有这些字体的代码,结果是完全相同:字符0x660E变为无效。

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    static HFONT s_hFont;   

    switch( message )
    {
        case WM_CREATE:
        {
            LOGFONT lf;
            memset(&lf, 0, sizeof(LOGFONT));
            lf.lfHeight = -MulDiv(20, 96, 72);
            lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
            wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Calibri");

            if( !(s_hFont = CreateFontIndirect(&lf)) ) return -1;
        }
        break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            s_hFont = (HFONT)SelectObject(ps.hdc, s_hFont);

            wchar_t wchar1 = 0x062A;                //  Arabic character
            TextOut(ps.hdc, 10, 10, &wchar1, 1);

            wchar_t wchar2 = 0x660E;                //  Japanese character
            TextOut(ps.hdc, 10, 50, &wchar2, 1);

            s_hFont = (HFONT)SelectObject(ps.hdc, s_hFont);
            EndPaint(hwnd, &ps);
        }
        break;


        case WM_DESTROY:
        DeleteObject(s_hFont);
        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0L ;
}

输出屏幕截图

enter image description here

2 个答案:

答案 0 :(得分:3)

我怀疑你会得到一个非常好的答案,因为字体链接并没有很好地记录,没有人真正关心它(我会解释的原因)。

Michael Kaplan撰写了一系列关于这一主题的短文:字体替换和链接部分123。并且有一个MSDN article

正如Michael Kaplan所指出的,字体链接取决于当前的系统区域设置,也可以在任何系统上进行编辑。你不能依赖它。

因此,任何关心处理多语言文本的应用程序都将使用MLangUniscribe或其他一些库来确保获得良好的结果。

大多数应用程序不需要此级别的国际支持。处理用户自己的脚本通常就足够了,Windows主要是为您做这件事。例如,我的日语用户想要输入日文文本;他们不在乎乌尔都语是否在他们的计算机上不起作用。反之亦然,巴基斯坦的用户。

总之,如果您不关心支持多于用户的脚本,请使用Windows默认值。如果您关心,请使用库来输出文本。不要依赖字体链接。

答案 1 :(得分:0)

  

Windows核心字体(Times New Roman,Courier New,Arial,Microsoft Sans Serif和Tahoma)包含拉丁语,希伯来语,阿拉伯语,希腊语和西里尔语脚本,但不包含东亚脚本字符。它们链接到的字体。

而且,确实他们确实链接到支持CJK的字体,但这并不意味着你已经安装了这些字体。您没有指定哪个版本的Windows。在旧版本(例如XP和Vista)上,如果安装“西方”版本,除非明确要求Windows安装必要的字体和表格,否则不会获得良好的CJK字体支持。

有一个控制面板应用程序(区域设置?),可以让您表明您想要更完整的国际角色支持。它将需要您的安装媒体,它将安装更多字体并更新与这些附加字符相关的表。它甚至可能更新链接注册表项的字体。