Windows系统字体的点阵显示示例

本程序实现在对话框界面上以Windows系统字体转为点阵的形式显示字符或汉字

 

新建对话框程序:
1.加入成员变量: 
byte* m_pBuf; //子体数据缓冲区
int m_nWidth;//字体实际宽度
int m_nHeight;//字体实际高度

 

2.加入成员函数:
void freeData()
{
 if ( m_pBuf )
 {
  free( m_pBuf );
  m_pBuf = NULL;
 }
}

//浮点数据转换为固定浮点数。
FIXED FixedFromDouble(double d)
{
 long l;
 l = (long) (d * 65536L);
 return *(FIXED *)&l;
}

//设置字体图形变换矩阵。
void SetMat(LPMAT2 lpMat)
{
 lpMat->eM11 = FixedFromDouble(2);
 lpMat->eM12 = FixedFromDouble(0);
 lpMat->eM21 = FixedFromDouble(0);
 lpMat->eM22 = FixedFromDouble(2);
}


3.构造函数中加入:
m_pBuf = NULL;
m_nWidth = 0;
m_nHeight = 0;

 

4.析构函数中加入:
freeData();

 

5.定制一按钮实现如下代码:
CFontDialog dlg;
if ( IDOK == dlg.DoModal())
{
 LOGFONT lf;
 dlg.GetCurrentFont( &lf );

 //创建字体。
 HFONT hFont = CreateFontIndirect( &lf) ;
 CFont* pFont = CFont::FromHandle( hFont );

 //设置字体到当前设备。
 CDC*pDC = GetDC();
 CFont* pOldFont = pDC->SelectObject( pFont );

 //设置字体图形变换矩阵        
 MAT2 mat2;
 SetMat(&mat2);

 GLYPHMETRICS gm;

 //设置要显示的字符。     
 //TCHAR ch = L'@';
    TCHAR ch = L'章';

 //获取这个字符图形需要的字节的大小。
 DWORD dwNeedSize = pDC->GetGlyphOutline(ch,GGO_BITMAP,&gm,0,NULL,&mat2);
 if (dwNeedSize > 0 && dwNeedSize < 0xFFFF)
 { 
  freeData();
  m_pBuf = (byte*)(malloc(dwNeedSize));
  if ( m_pBuf)
  {
   //获取字符图形的数据到缓冲区。
   pDC->GetGlyphOutline(ch,GGO_BITMAP,&gm,dwNeedSize,m_pBuf,&mat2);
            m_nWidth = gm.gmBlackBoxX;
   m_nHeight = gm.gmBlackBoxY;
   
   
   //下面只是为了在调试窗查看数据,可以不要
//////////////////////////////////////////////////////////////////////////
/*   //计算图形每行占用的字节数。
   int nByteCount = ((gm.gmBlackBoxX +31) >> 5) << 2;   
   //显示每行图形的数据。   
   for (int i = 0; i < gm.gmBlackBoxY; i++)
   {
    for (int j = 0; j < nByteCount; j++)
    {
     BYTE btCode = m_pBuf[i* nByteCount + j];

     CString str;
     str.Format( _T("%x "),btCode );
     OutputDebugString( str );

     //按字节输出每点的数据。
//      for (int k = 0; k < 8; k++)
//      {                         
//       if (btCode & (0x80>>k))
//       {                    
//        OutputDebugString(_T("1"));
//       }
//       else
//       {
//        OutputDebugString(_T("0"));
//       }         
//      }                         

    }
    OutputDebugString(_T("/r/n"));
   } */
//////////////////////////////////////////////////////////////////////////
  }

  Invalidate( TRUE );
 }

 
 pDC->SelectObject(pOldFont);
 DeleteObject(hFont);
 ReleaseDC(pDC);

}

 

6.在对话款的OnPaint函数中的CDialog::OnPaint()前面实现如下代码:
if(m_pBuf != NULL)
{
 CPaintDC dc(this); // 用于绘制的设备上下文
 CRect rect;
 GetClientRect(&rect);
 int x = rect.left + 10;
 int y = rect.top + 10;
 int dx = 0;
 int dy = 0;
 int dsize = 10;

 byte* pStr = m_pBuf;
 //计算图形每行占用的字节数(4字节对齐)
 int nLen = ((m_nWidth +31) >> 5) << 2;
 for( int j=0; j<m_nHeight; j++)
 {
  dy = y + j * dsize;
  for(int i=0; i<nLen; i++)
  {
      dx = x + i * 8 * dsize;
   byte val = *pStr;
   for( int bit=0; bit<8 ; bit++)
   {
    dc.FillSolidRect(dx, dy, dsize, dsize, (val & (0x80 >> bit)) ? RGB(0,0,0) : RGB(255,255,255));
    dx = dx + dsize;    
   }
   pStr++;
  }
 }
}

注意:显示汉字字体时要采用 Unicode 字符集编码。

你可能感兴趣的:(windows,null,byte,图形)