Calibri
字体既没有其中一个字符,0x062A
和0x660E
,但第一个字符使用其他字体打印。但是,字符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 ;
}
输出屏幕截图
答案 0 :(得分:3)
我怀疑你会得到一个非常好的答案,因为字体链接并没有很好地记录,没有人真正关心它(我会解释的原因)。
Michael Kaplan撰写了一系列关于这一主题的短文:字体替换和链接部分1,2和3。并且有一个MSDN article。
正如Michael Kaplan所指出的,字体链接取决于当前的系统区域设置,也可以在任何系统上进行编辑。你不能依赖它。
因此,任何关心处理多语言文本的应用程序都将使用MLang或Uniscribe或其他一些库来确保获得良好的结果。
大多数应用程序不需要此级别的国际支持。处理用户自己的脚本通常就足够了,Windows主要是为您做这件事。例如,我的日语用户想要输入日文文本;他们不在乎乌尔都语是否在他们的计算机上不起作用。反之亦然,巴基斯坦的用户。
总之,如果您不关心支持多于用户的脚本,请使用Windows默认值。如果您关心,请使用库来输出文本。不要依赖字体链接。
答案 1 :(得分:0)
Windows核心字体(Times New Roman,Courier New,Arial,Microsoft Sans Serif和Tahoma)包含拉丁语,希伯来语,阿拉伯语,希腊语和西里尔语脚本,但不包含东亚脚本字符。它们链接到的字体。
而且,确实他们确实链接到支持CJK的字体,但这并不意味着你已经安装了这些字体。您没有指定哪个版本的Windows。在旧版本(例如XP和Vista)上,如果安装“西方”版本,除非明确要求Windows安装必要的字体和表格,否则不会获得良好的CJK字体支持。
有一个控制面板应用程序(区域设置?),可以让您表明您想要更完整的国际角色支持。它将需要您的安装媒体,它将安装更多字体并更新与这些附加字符相关的表。它甚至可能更新链接注册表项的字体。