最近想在FPGA上做OSD, 既在视频信号上叠加上文字信息,考虑到使用点阵字库提取的办法样式比较单一,因此选择利用Windows的TTF字库,参考了网上的一些资料,现己试验成功,主要的VC++代码分享如下:
LOGFONT lf;
CFont newfont;
lf.lfHeight = 10; //字体宽
lf.lfWidth = 10; //字体高
lf.lfUnderline = 0; //下划线
lf.lfStrikeOut = 0; //删除线
CFontDialog cf(&lf);
if(cf.DoModal() == IDOK)
{
cf.GetCurrentFont(&lf);
newfont.CreateFontIndirect(&lf);
} //选择并创建字体
CDC* pdc=this->GetDC();
CFont *poldfont=pdc->SelectObject(&newfont); //把字体选入当前的设备上下文
MAT2 mmat2={0,1,0,0,0,0,0,1}; //字符信息转换矩阵
GLYPHMETRICS glpm; //用于描述字表在字符单元的放置
DWORD nLen;
UINT chartemp;
BYTE temp;
CString str="字";
temp = str.GetAt(0);
if( temp>128 )
{
chartemp=((UINT)temp)<<8;
temp=str.GetAt(1);
chartemp+=temp;
}
else
{
chartemp=temp;
}
nLen=::GetGlyphOutline(pdc->GetSafeHdc(),chartemp,1,&glpm,0,NULL,&mmat2);
unsigned int nx = glpm.gmBlackBoxX; //字体宽
unsigned int ny = glpm.gmBlackBoxY; //字体高
if((signed)nLen>0)
{
BYTE* pBuf;
pBuf = new BYTE[nLen];
//用GetGlyphOutline函数获取字模信息
DWORD nLentemp=::GetGlyphOutline(pdc->GetSafeHdc(),chartemp,1,&glpm,nLen,pBuf,&mmat2);
if(nLentemp!=nLen)
{
MessageBox("字体太大");
return;
}
unsigned int charLineW = (glpm.gmBlackBoxX/32+(glpm.gmBlackBoxX%32==0?0:1))*4;
unsigned int xloop,xleft,x_Index;
BYTE Data;
BYTE * pData = pBuf;
CClientDC dc(this);
unsigned int nGridStep = 8;
for(unsigned int ly = 0; ly < ny; ly++)
{
xleft = nx;
x_Index = 0;
while(1)
{
if(xleft == 0) break;
else if(xleft >= 8) {xloop = 8; xleft -= 8;}
else
{
xloop = xleft;
xleft = 0;
}
Data = *(pData + ly*charLineW + (x_Index)/8 + ((x_Index%8)==0?0:1) );
for( unsigned int i = 0; i< xloop; i++,x_Index++)
{
BYTE Bit = (Data<<(i)) & 0x80;
if(Bit)
{
dc.Ellipse( x_Index * nGridStep,
ly*nGridStep,
( x_Index + 1 )*nGridStep,
(ly +1 )*nGridStep
);
}
}
}
}
}
else
{
MessageBox("字体太大");
}
相信该方法对嵌入式系统的文字显示有很大的帮助,可以根据自己的需要建一个小库,而且字体可以多样化。