Ttf字体文件编辑

Windows矢量字体的提取(转换)在很多场合都需要汉字的显示,比如公交报站用的电子显示牌,商场显示各种商品信息。Windows提供了丰富的字体库。如何利用这些字库来显示汉字,是一个需要解决的问题。Windows支持GDI字体和设备字体。GDI字体存储在硬盘文件中,而设备字体是输出设备固有的。GDI字体分为三种:点阵字体、笔画字体和TrueType字体。点阵字体的字体可以直接从字体文件中获取,后两种是矢量字体,不能直接获取其字体。因此,必须对笔画字体和TrueType字体进行栅格化,以获得所需的字体。

通常电子系统的信息显示使用的是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丰富的字体库中提取各种字体的字体,不再局限于单一字体,从而丰富了电子显示系统的设计。如果是从点阵字体中提取字体的话,有一些缺点,最重要的是可供选择的字体太少。此外,利用本文介绍的方法可以提取简单的图像点阵,丰富了电子显示系统的设计。

这是别人空间的,但是我看不懂。希望对你有帮助。