admin 2007-12-18 11:29
GetGlyphOutline函数
[size=10.5pt]中西文化的差异,导致在电子信息里处理也大不相同,在英文里只需要[/size][size=10.5pt]26[/size][size=10.5pt]个字母就可以显示所有文章了,而在中文里需要最基本的字符就有[/size][size=10.5pt]2000[/size][size=10.5pt]多个。对于一些在嵌入式软件里要显示的字符,那么就得手动去构造所有图形,这是一个比较大的工作量,如果让每个厂家都去完成这个任务,显然是不可能的。面对着大量嵌入式用户的需求,那么就需要解决中文字模的图形问题。毕竟大家经常使用[/size][size=10.5pt]Windows[/size][size=10.5pt],最先想到的,肯定是怎么样把里面的字符提取图形出来,生成自己需要的几个字库。下面就来介绍怎么样用函数[/size][size=10.5pt]GetGlyphOutline[/size][size=10.5pt]获取显示字符的图形数据。[/size]
[size=10.5pt]函数[/size][size=10.5pt]GetGlyphOutline[/size][size=10.5pt]声明如下:[/size]
[size=10.5pt]WINGDIAPI DWORD WINAPI GetGlyphOutlineA( __in HDC hdc,[/size]
[size=10.5pt] __in UINT uChar,[/size]
[size=10.5pt] __in UINT fuFormat,[/size]
[size=10.5pt] __out LPGLYPHMETRICS lpgm,[/size]
[size=10.5pt] __in DWORD cjBuffer,[/size]
[size=10.5pt] __out_bcount_opt(cjBuffer) LPVOID pvBuffer,[/size]
[size=10.5pt] __in CONST MAT2 *lpmat2[/size]
[size=10.5pt] );[/size]
[size=10.5pt]WINGDIAPI DWORD WINAPI GetGlyphOutlineW( __in HDC hdc,[/size]
[size=10.5pt] __in UINT uChar,[/size]
[size=10.5pt] __in UINT fuFormat,[/size]
[size=10.5pt] __out LPGLYPHMETRICS lpgm,[/size]
[size=10.5pt] __in DWORD cjBuffer,[/size]
[size=10.5pt] __out_bcount_opt(cjBuffer) LPVOID pvBuffer,[/size]
[size=10.5pt] __in CONST MAT2 *lpmat2[/size]
[size=10.5pt] );[/size]
[size=10.5pt]#ifdef UNICODE[/size]
[size=10.5pt]#define GetGlyphOutline GetGlyphOutlineW[/size]
[size=10.5pt]#else[/size]
[size=10.5pt]#define GetGlyphOutline GetGlyphOutlineA[/size]
[size=10.5pt]#endif // !UNICODE[/size]
[b][i][size=10.5pt]hdc[/size][/i][/b][size=10.5pt]是设备句柄。[/size]
[b][i][size=10.5pt]uChar[/size][/i][/b][size=10.5pt]是需要获取图形数据的字符。[/size]
[b][i][size=10.5pt]fuFormat[/size][/i][/b][size=10.5pt]是获取数据的格式。[/size]
[b][i][size=10.5pt]lpgm[/size][/i][/b][size=10.5pt]是获取字符的相关信息。[/size]
[b][i][size=10.5pt]cjBuffer[/size][/i][/b][size=10.5pt]是保存字符数据的缓冲区大小。[/size]
[b][i][size=10.5pt]pvBuffer[/size][/i][/b][size=10.5pt]是保存字符数据的缓冲区。[/size]
[b][i][size=10.5pt]lpmat2[/size][/i][/b][size=10.5pt]是[/size][size=10.5pt]3*3[/size][size=10.5pt]的变换矩阵。[/size]
[size=10.5pt]调用函数的例子如下:[/size]
[size=10.5pt]#001 //[/size][size=10.5pt]浮点数据转换为固定浮点数。[/size]
[size=10.5pt]#002 FIXED FixedFromDouble(double d)[/size]
[size=10.5pt]#003 {[/size]
[size=10.5pt]#004 long l;[/size]
[size=10.5pt]#005 l = (long) (d * 65536L);[/size]
[size=10.5pt]#006 return *(FIXED *)&l;[/size]
[size=10.5pt]#007 }[/size]
[size=10.5pt]#008 [/size]
[size=10.5pt]#009 //[/size][size=10.5pt]设置字体图形变换矩阵。[/size]
[size=10.5pt]#010 void SetMat(LPMAT2 lpMat)[/size]
[size=10.5pt]#011 {[/size]
[size=10.5pt]#012 lpMat->eM11 = FixedFromDouble(2);[/size]
[size=10.5pt]#013 lpMat->eM12 = FixedFromDouble(0);[/size]
[size=10.5pt]#014 lpMat->eM21 = FixedFromDouble(0);[/size]
[size=10.5pt]#015 lpMat->eM22 = FixedFromDouble(2);[/size]
[size=10.5pt]#016 }[/size]
[size=10.5pt]#017 [/size]
[size=10.5pt]#018 //[/size]
[size=10.5pt]#019 //[/size][size=10.5pt]获取字模信息。[/size]
[size=10.5pt]#020 //[/size][size=10.5pt]蔡军生[/size][size=10.5pt] 2007/12/16 QQ:9073204 [/size][size=10.5pt]深圳[/size]
[size=10.5pt]#021 void TestFontGlyph(void)[/size]
[size=10.5pt]#022 {[/size]
[size=10.5pt]#023 //[/size][size=10.5pt]创建字体。[/size]
[size=10.5pt]#024 HFONT hFont = GetFont();[/size]
[size=10.5pt]#025 [/size]
[size=10.5pt]#026 //[/size][size=10.5pt]设置字体到当前设备。[/size]
[size=10.5pt]#027 HDC hDC = ::GetDC(m_hWnd);[/size]
[size=10.5pt]#028 HFONT hOldFont = (HFONT)SelectObject(hDC,hFont);[/size]
[size=10.5pt]#029 [/size]
[size=10.5pt]#030 //[/size][size=10.5pt]设置字体图形变换矩阵[/size]
[size=10.5pt]#031 MAT2 mat2;[/size]
[size=10.5pt]#032 SetMat(&mat2);[/size]
[size=10.5pt]#033 [/size]
[size=10.5pt]#034 [/size]
[size=10.5pt]#035 GLYPHMETRICS gm;[/size]
[size=10.5pt]#036 [/size]
[size=10.5pt]#037 //[/size][size=10.5pt]设置要显示的字符。[/size]
[size=10.5pt]#038 TCHAR chText = L'[/size][size=10.5pt]蔡[/size][size=10.5pt]';[/size]
[size=10.5pt]#039 [/size]
[size=10.5pt]#040 //[/size][size=10.5pt]获取这个字符图形需要的字节的大小。[/size]
[b][size=10.5pt]#041 DWORD dwNeedSize = GetGlyphOutline(hDC,chText,GGO_BITMAP,&gm,0,NULL,&mat2);[/size][/b]
[size=10.5pt]#042 if (dwNeedSize > 0 && dwNeedSize < 0xFFFF)[/size]
[size=10.5pt]#043 {[/size]
[size=10.5pt]#044 //[/size][size=10.5pt]按需要分配内存。[/size]
[size=10.5pt]#045 LPBYTE lpBuf = (LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNeedSize);[/size]
[size=10.5pt]#046 if (lpBuf)[/size]
[size=10.5pt]#047 {[/size]
[size=10.5pt]#048 //[/size][size=10.5pt]获取字符图形的数据到缓冲区。[/size]
[b][size=10.5pt]#049 GetGlyphOutline(hDC,chText,GGO_BITMAP,&gm,dwNeedSize,lpBuf,&mat2);[/size][/b]
[size=10.5pt]#050 [/size]
[size=10.5pt]#051 //[/size][size=10.5pt]计算图形每行占用的字节数。[/size]
[size=10.5pt]#052 int nByteCount = ((gm.gmBlackBoxX +31) >> 5) << 2;[/size]
[size=10.5pt]#053 [/size]
[size=10.5pt]#054 //[/size][size=10.5pt]显示每行图形的数据。[/size]
[size=10.5pt]#055 for (int i = 0; i < gm.gmBlackBoxY; i++)[/size]
[size=10.5pt]#056 {[/size]
[size=10.5pt]#057 // [/size]
[size=10.5pt]#058 for (int j = 0; j < nByteCount; j++)[/size]
[size=10.5pt]#059 {[/size]
[size=10.5pt]#060 [/size]
[size=10.5pt]#061 BYTE btCode = lpBuf[i* nByteCount + j];[/size]
[size=10.5pt]#062 [/size]
[size=10.5pt]#063 //[/size][size=10.5pt]按字节输出每点的数据。[/size]
[size=10.5pt]#064 for (int k = 0; k < 8; k++)[/size]
[size=10.5pt]#065 { [/size]
[size=10.5pt]#066 [/size]
[size=10.5pt]#067 if (btCode & (0x80>>k))[/size]
[size=10.5pt]#068 { [/size]
[size=10.5pt]#069 [/size]
[size=10.5pt]#070 OutputDebugString(_T("1"));[/size]
[size=10.5pt]#071 }[/size]
[size=10.5pt]#072 else[/size]
[size=10.5pt]#073 {[/size]
[size=10.5pt]#074 OutputDebugString(_T("0"));[/size]
[size=10.5pt]#075 } [/size]
[size=10.5pt]#076 [/size]
[size=10.5pt]#077 } [/size]
[size=10.5pt]#078 [/size]
[size=10.5pt]#079 }[/size]
[size=10.5pt]#080 [/size]
[size=10.5pt]#081 //[/size]
[size=10.5pt]#082 OutputDebugString(_T("\r\n"));[/size]
[size=10.5pt]#083 }[/size]
[size=10.5pt]#084 [/size]
[size=10.5pt]#085 //[/size]
[size=10.5pt]#086 HeapFree(GetProcessHeap(),0,lpBuf);[/size]
[size=10.5pt]#087 }[/size]
[size=10.5pt]#088 }[/size]
[size=10.5pt]#089 [/size]
[size=10.5pt]#090 //[/size]
[size=10.5pt]#091 SelectObject(hDC,hOldFont);[/size]
[size=10.5pt]#092 DeleteObject(hFont);[/size]
[size=10.5pt]#093 [/size]
[size=10.5pt]#094 //[/size]
[size=10.5pt]#095 ReleaseDC(m_hWnd,hDC);[/size]
[size=10.5pt]#096 }[/size]
[size=10.5pt]#097 [/size]
[size=10.5pt]输出的结果如下:[/size]
[size=10.5pt]00000000000000010000000000000000[/size]
[size=10.5pt]00000000110000011000000000000000[/size]
[size=10.5pt]00000000100000011000000000000000[/size]
[size=10.5pt]00000000100000011000011000000000[/size]
[size=10.5pt]11111111111111111111111100000000[/size]
[size=10.5pt]01000000100000011000000000000000[/size]
[size=10.5pt]00000000100000011000000000000000[/size]
[size=10.5pt]00000100100000011000000000000000[/size]
[size=10.5pt]00000110100000010000000000000000[/size]
[size=10.5pt]00000100000000000000000000000000[/size]
[size=10.5pt]00001100000001000000100000000000[/size]
[size=10.5pt]00001111111101111111110000000000[/size]
[size=10.5pt]00001000001111000000110000000000[/size]
[size=10.5pt]00011000001000100001100000000000[/size]
[size=10.5pt]00010100001000100001000000000000[/size]
[size=10.5pt]00010010011000100011000000000000[/size]
[size=10.5pt]00100011010000010010000000000000[/size]
[size=10.5pt]00110010110000011010000000000000[/size]
[size=10.5pt]01011000110000001100000000000000[/size]
[size=10.5pt]10001000100000001100000000000000[/size]
[size=10.5pt]00001001100000010110000000000000[/size]
[size=10.5pt]00001011011111111011000000000000[/size]
[size=10.5pt]00000010000000000001110000000000[/size]
[size=10.5pt]00000110000000000000111100000000[/size]
[size=10.5pt]00001100000000000110011100000000[/size]
[size=10.5pt]00011111111111111111001000000000[/size]
[size=10.5pt]00110000000010000000000000000000[/size]
[size=10.5pt]01000000000010000000000000000000[/size]
[size=10.5pt]00000001000010000000000000000000[/size]
[size=10.5pt]00000011100010001100000000000000[/size]
[size=10.5pt]00000011000010000010000000000000[/size]
[size=10.5pt]00000110000010000011100000000000[/size]
[size=10.5pt]00001100000010000001100000000000[/size]
[size=10.5pt]00011000100010000000110000000000[/size]
[size=10.5pt]00110000011110000000110000000000[/size]
[size=10.5pt]01000000001110000000010000000000[/size]
[size=10.5pt]00000000000100000000000000000000[/size]