Windows API一日一練(90)GetGlyphOutline函數

來源:互聯網
上載者:User
  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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.