Calibri
字体中没有字符0x062A
和0x660E
,但是第一个字符使用其他字体打印。然而,字符0x660E
显示为无效字符代码。为什么TextOut()
不替换字体以打印这个字符,就像它用字符代码0x062A
做的那样?如果我用
Arial
字体替换Calibri
字体,结果是一样的。此外,我想引起你的注意,可以在这里找到这句话:http://msdn.microsoft.com/en-us/goglobal/bb688134.aspx:“Windows核心字体(Times New Roman,Courier New,Arial,Microsoft Sans Serif和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 ;
}
输出结果的截屏
0x062A
的字形,但没有0x660E
的字形。 - Benjamin LindleyTextOut()
的字体回退如何工作,它使用哪些字体以及如何查询和更改该字体列表。 - bames530x062A
是“阿拉伯字母泰”,0x660E
是CJK(中日韩)表意文字。UnicodeData.txt 表明从0x4E00
到0x9FCC
的范围都是CJK表意文字;它没有提供比这更多的信息。一个字体没有为该范围内的所有20,941个字符提供表示形式并不奇怪。 - Keith Thompson