Ttf字体文件编辑
通常电子系统的信息显示使用的是16×16(32字节)的点阵字体,比如Win98下的Chs16.fon就是16×16(32字节)的字体文件。从中提取字体的方法是:汉字内码为两个字节,分别设置为A和b,A的大小应该在0xa1和0xfe之间,其区号为qu=a-0xa0,位码为wei=b-0xa0,汉字字体在字体文件中的位置为offset =((qu-1)×94+(Wei-1))×32。
本文主要介绍了从Windows的矢量字体中提取字体的方法。该方法已成功应用于单片机系统的设计中,解决了汉字显示问题。在实际应用中,可以直接调用Win32 API函数,将需要提取的汉字文本转换成位图,从而实现汉字的点阵,提取字体。
1字体设置
你需要先设置字体。Win32 SDK提供了一个通用的字体选择对话框,只需调用ChooseFont函数,其返回值是一个布尔值。具体定义为boolchoosefont(lpchoosefont lpcf)。调用该函数后,弹出字体选择对话框,可以选择所需的字体、字形、字号等参数。选择后,如果在字体选择对话框中点击确定,该函数返回一个非零值;如果单击Cancel键,该函数将返回一个零值。在调用这个函数之前,您需要定义两个变量:
选择字体cf;
LOGFONT logfont
CHOOSEFONT是一个有十多个字段的结构,其中包含ChooseFont函数用来初始化字体选择对话框的各种信息。LOGFONT也是一个结构,包含14个字段,定义了字体的各种属性。点击确定后,系统通过LOGFONT结构返回选中的字体信息。返回的字体信息存储在由CHOOSEFONT结构的lpLogFont字段指定的LOGFONT结构中。
以下是调用ChooseFont函数的代码:
//初始化CHOOSEFONT
cf . l structsize = sizeof(choose font);
cf.hwndOwner = hwnd//当前窗口的句柄
cf.hDC = NULL
cf.lpLogFont = & amplogfont//这里保存系统返回的字体信息。
cf . ipointsize = 0;
CF . Flags = CF _ INITTOLOGFONTSTRUCT | CF _
屏幕字体| CF _ EFFECTS
cf . RGB colors = 0;
cf . lcustdata = 0;
cf.lpfnHook = NULL
cf.lpTemplateName = NULL
cf.hInstance = NULL
cf.lpszStyle = NULL
cf . nfonttype = 0;
cf . NSI Zemin = 0;
cf . nsizemax = 0;
选择字体(& ampcf);//调用该函数后,弹出字体选择的通用对话框。
如果选择字体(&;Cf)函数返回一个非零值,那么字体已经被选中。所选字体保存在logfont变量中。接下来要做的是创建选定的逻辑字体。您可以调用CreateFontIndirect函数来创建逻辑字体。CreateFontIndirect函数接受指向LOGFONT结构的指针,具体定义为hfont CreateFontIndirect(constlogfont?Lplf)。代码如下:
HFONT hNewFont = CreateFontIndirect(& amp;log font);
至此,字体创建完成。通过直接调用SeletObject函数,可以将创建的逻辑字体选择到设备描述表中。在位图转换中,将使用SelectObject函数将hNewFont选择到内存设备描述表中。但需要注意的是,在程序结束之前,必须调用DeleteObject(hNewFont)函数来释放字体句柄,以避免内存泄漏。下面介绍将文本转换成位图的具体实现过程。
2位图转换
这里给出一个提取“ting”字体的例子。首先,您需要定义以下变量:
静态WCHAR汉字[]= " Ting ";
静态HBITMAP hBitmap
静态int cxBitmap,cyBitmap
静态HDC hdc,hdcMem
PAINTSTRUCT ps
尺寸大小;
CxBitmap和cybermap是要创建的位图的大小,与GetTextExtentPoint32函数得到的文本大小一致,也就是这里的“Ting”字的大小。
下面是汉字文本转换成位图的具体方法,一般在WM_PAINT消息中处理。
案例WM_PAINT:
hdc = begin paint(hwnd & amp;PS);//获取当前窗口的设备句柄。
hdc mem = CreateCompatileDC(hdc);//创建内存设备描述表。
SelectObject(hdcMem,hNewFont);//将创建的字体选择到内存设备描述表中。
GetTextExtendPoint32W(hdcMem,Hanzi,1,& amp尺寸);
//获取要显示的文本的大小。
cxBitmap = size.cx
cyBitmap = size.cy
hbit map = createcompatiletibbitmap(hdc,cxBitmap,
cyBitmap);//创建位图句柄
SelectObject(hdcMem,hbit map);//选择位图到内存设备描述表中。
TextOutW(hdcMem,0,0,汉字,1);//在内存设备描述表的位图上画汉字。
BitBlt(hdc,0,0,cxBitmap,cyBitmap,hdcMem,0,0,SRC-
复制);//在窗口的客户区显示位图,观察显示效果。
至此,汉字的点阵过程完成,接下来就要提取字体了。
3提取字体
GetPixel函数用于提取字体,定义为COLORREF GetPixel(HDC hdc,int nXPos,int nYPos)。该函数返回COLORREF类型的值,即nXPos和nYPos指定的点的RGB值。位图的大小在上一篇文章中已经确定了。在这个范围内,每个像素点扫描一次,根据返回的RGB值生成位图代码。因为Windows矢量字体是有灰度的,所以要选择一个合适的RGB值来判断这个点是否有效。白色的RGB值是FFFFFFH,深灰色的是808080H,黑色的是000000H。可以选择深灰色作为判断依据。当函数的返回值小于808080H时,此点被认为是有效的。下面是提取字体的函数,以字节存储,从第一行的第一点开始扫描:
静墨子[2048];//此数组中存在格码。
void GetZimo(HDC hdc,int nXPos,int nYPos)
{
int Hang,Lie//Hang是扫描的行数。
int temp,I,j,g;
Hang = nYPos
Lie = nXPos
if(Lie % 8==0 ){
Lie = Lie/8;//位图的宽度是8的整数倍,所以
//存储字体只需要Lie/8字节。
temp = 0;
}
否则{
temp = Lie % 8;
Lie = Lie/8+1;//位图的宽度不是8的整数倍。
//所以存储字体只需要Lie/8+1字节。
}
memset(墨子,0,2048);//将字体数组设置为全零。
for(I = 0;我& lt挂;i++){
for(j = 0;j & lt撒谎;j++){
如果((temp!= 0)& amp;& amp(j==Lie-1) ){
for(k = 0;k & lt温度;k++){
g=(int)GetPixel(hdc,j*8+k,I);
if(g & lt;0x00808080)
墨子[i*Lie+j]+=(无符号
char)pow(2,7-k);
}
}
否则{
for(k = 0;k & lt8;k++){
g=(int)GetPixel(hdc,j*8+k,I);
if(g & lt;0x00808080)
墨子[i*Lie+j]+=(无符号
char)pow(2,7-k);
}
}
}
}
}
在WM_PAINT消息中,调用GetZimo(hdcMem,cxBit-
Map,cyBitmap)可以得到汉字的字体。在程序结束时,您还必须做一些收尾工作:
delete object(hbit map);//使用后必须发布设备描述。
//表格和位图句柄以避免内存泄漏
delete object(hNewFont);
DeleteDC(hdc mem);
面漆(hwnd & amp;PS);
返回0;//WM_PAINT消息处理后返回。
4输出结果
以“挺”字为例,弹出字体选择对话框后,字体选择为新歌体,字体选择为正常,字号选择为小二。Hang=24,Lie=3,存储72个字节。字体为00H,00H,00H,00H,00H,03H,00H,04H,01H,80H,04H,01H,0CH,04H,3EH,F0H,0CH,00H,7h。18H,8FH,F0H,10H,90H,04H,11H,BFH,FEH,11H,20H,04H,31H,60H,08H,21H,40H,18H,65438在纸上画一个点阵码,正好是“亭”字,如图1。从cxBitmap和cyBitmap可以知道“婷”的点阵大小是24×24。
5结束语
利用文本转位图的方法,可以从Windows丰富的字体库中提取各种字体的字体,不再局限于单一字体,从而丰富了电子显示系统的设计。如果是从点阵字体中提取字体的话,有一些缺点,最重要的是可供选择的字体太少。此外,利用本文介绍的方法可以提取简单的图像点阵,丰富了电子显示系统的设计。
这是别人空间的,但是我看不懂。希望对你有帮助。