Windows API一日一練(90)GetGlyphOutline函數
中西文化的差異,導致在電子資訊裡處理也大不相同,在英文裡只需要26個字母就可以顯示所有文章了,而在中文裡需要最基本的字元就有2000多個。對於一些在嵌入式軟體裡要顯示的字元,那麼就得手動去構造所有圖形,這是一個比較大的工作量,如果讓每個廠家都去完成這個任務,顯然是不可能的。面對著大量嵌入式使用者的需求,那麼就需要解決中文字模的圖形問題。畢竟大家經常使用Windows,最先想到的,肯定是怎麼樣把裡面的字元提取圖形出來,產生自己需要的幾個字型檔。下面就來介紹怎麼樣用函數GetGlyphOutline擷取顯示字元的圖形資料。
函數GetGlyphOutline聲明如下:
WINGDIAPI DWORD WINAPI GetGlyphOutlineA( __in HDC hdc,
__in UINT uChar,
__in UINT fuFormat,
__out LPGLYPHMETRICS lpgm,
__in DWORD cjBuffer,
__out_bcount_opt(cjBuffer) LPVOID pvBuffer,
__in CONST MAT2 *lpmat2
);
WINGDIAPI DWORD WINAPI GetGlyphOutlineW( __in HDC hdc,
__in UINT uChar,
__in UINT fuFormat,
__out LPGLYPHMETRICS lpgm,
__in DWORD cjBuffer,
__out_bcount_opt(cjBuffer) LPVOID pvBuffer,
__in CONST MAT2 *lpmat2
);
#ifdef UNICODE
#define GetGlyphOutline GetGlyphOutlineW
#else
#define GetGlyphOutline GetGlyphOutlineA
#endif // !UNICODE
hdc是裝置控制代碼。
uChar是需要擷取圖形資料的字元。
fuFormat是擷取資料的格式。
lpgm是擷取字元的相關資訊。
cjBuffer是儲存字元資料的緩衝區大小。
pvBuffer是儲存字元資料的緩衝區。
lpmat2是3*3的變換矩陣。
調用函數的例子如下:
#001 //浮點數據轉換為固定浮點數。
#002 FIXED FixedFromDouble(double d)
#003 {
#004 long l;
#005 l = (long) (d * 65536L);
#006 return *(FIXED *)&l;
#007 }
#008
#009 //設定字型圖形變換矩陣。
#010 void SetMat(LPMAT2 lpMat)
#011 {
#012 lpMat->eM11 = FixedFromDouble(2);
#013 lpMat->eM12 = FixedFromDouble(0);
#014 lpMat->eM21 = FixedFromDouble(0);
#015 lpMat->eM22 = FixedFromDouble(2);
#016 }
#017
#018 //
#019 //擷取字模資訊。
#020 //蔡軍生 2007/12/16 QQ:9073204 深圳
#021 void TestFontGlyph(void)
#022 {
#023 //建立字型。
#024 HFONT hFont = GetFont();
#025
#026 //設定字型到當前裝置。
#027 HDC hDC = ::GetDC(m_hWnd);
#028 HFONT hOldFont = (HFONT)SelectObject(hDC,hFont);
#029
#030 //設定字型圖形變換矩陣
#031 MAT2 mat2;
#032 SetMat(&mat2);
#033
#034
#035 GLYPHMETRICS gm;
#036
#037 //設定要顯示的字元。
#038 TCHAR chText = L'蔡';
#039
#040 //擷取這個字元圖形需要的位元組的大小。
#041 DWORD dwNeedSize = GetGlyphOutline(hDC,chText,GGO_BITMAP,&gm,0,NULL,&mat2);
#042 if (dwNeedSize > 0 && dwNeedSize < 0xFFFF)
#043 {
#044 //按需要分配記憶體。
#045 LPBYTE lpBuf = (LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNeedSize);
#046 if (lpBuf)
#047 {
#048 //擷取字元圖形的資料到緩衝區。
#049 GetGlyphOutline(hDC,chText,GGO_BITMAP,&gm,dwNeedSize,lpBuf,&mat2);
#050
#051 //計算圖形每行佔用的位元組數。
#052 int nByteCount = ((gm.gmBlackBoxX +31) >> 5) << 2;
#053
#054 //顯示每行圖形的資料。
#055 for (int i = 0; i < gm.gmBlackBoxY; i++)
#056 {
#057 //
#058 for (int j = 0; j < nByteCount; j++)
#059 {
#060
#061 BYTE btCode = lpBuf[i* nByteCount + j];
#062
#063 //按位元組輸出每點的資料。
#064 for (int k = 0; k < 8; k++)
#065 {
#066
#067 if (btCode & (0x80>>k))
#068 {
#069
#070 OutputDebugString(_T("1"));
#071 }
#072 else
#073 {
#074 OutputDebugString(_T("0"));
#075 }
#076
#077 }
#078
#079 }
#080
#081 //
#082 OutputDebugString(_T("/r/n"));
#083 }
#084
#085 //
#086 HeapFree(GetProcessHeap(),0,lpBuf);
#087 }
#088 }
#089
#090 //
#091 SelectObject(hDC,hOldFont);
#092 DeleteObject(hFont);
#093
#094 //
#095 ReleaseDC(m_hWnd,hDC);
#096 }
#097
輸出的結果如下:
00000000000000010000000000000000
00000000110000011000000000000000
00000000100000011000000000000000
00000000100000011000011000000000
11111111111111111111111100000000
01000000100000011000000000000000
00000000100000011000000000000000
00000100100000011000000000000000
00000110100000010000000000000000
00000100000000000000000000000000
00001100000001000000100000000000
00001111111101111111110000000000
00001000001111000000110000000000
00011000001000100001100000000000
00010100001000100001000000000000
00010010011000100011000000000000
00100011010000010010000000000000
00110010110000011010000000000000
01011000110000001100000000000000
10001000100000001100000000000000
00001001100000010110000000000000
00001011011111111011000000000000
00000010000000000001110000000000
00000110000000000000111100000000
00001100000000000110011100000000
00011111111111111111001000000000
00110000000010000000000000000000
01000000000010000000000000000000
00000001000010000000000000000000
00000011100010001100000000000000
00000011000010000010000000000000
00000110000010000011100000000000
00001100000010000001100000000000
00011000100010000000110000000000
00110000011110000000110000000000
01000000001110000000010000000000
00000000000100000000000000000000