3

The Calibri font doesn't have neither one of the characters, 0x062A and 0x660E, but the first character gets printed using some other font. However, the character 0x660E shows as an invalid char code. Why TextOut() doesn't substitute the font to print this last character, the same it did with the character code 0x062A ?

If I replace the Calibri font by Arial, the result is the same.

Edit : also I want to call your attention to this sentence, which can be found here http://msdn.microsoft.com/en-us/goglobal/bb688134.aspx : "The Windows core fonts (Times New Roman, Courier New, Arial, Microsoft Sans Serif, and Tahoma) contain Latin, Hebrew, Arabic, Greek, and Cyrillic scripts but do not contain East Asian script characters. They link to fonts that do." Well I've tried my code with all those fonts and the results were exactly the same : the character 0x660E is rendered invalid.

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 ;
}

Screen shot from the output

enter image description here

4

2 回答 2

3

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

Michael Kaplan 就该主题写了一系列简短的文章:字体替换和链接第 1部分、第 2部分和第 3部分。还有一篇MSDN 文章

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

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

大多数应用程序不需要这种级别的国际支持。处理用户自己的脚本通常就足够了,Windows 主要为您完成这些。比如我的日文用户想输入日文;他们不在乎乌尔都语是否不能在他们的电脑上工作。对于巴基斯坦的用户,反之亦然。

总之,如果您不关心支持的不仅仅是用户的脚本,请使用 Windows 默认值。如果您确实关心,请使用库进行文本输出。不要依赖字体链接。

于 2012-07-01T20:04:00.817 回答
0

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

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

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

于 2013-07-28T23:24:36.023 回答