根据所选择的 TrueType 字体生成点阵数据

2016-01-29 11:59 13 1 收藏

根据所选择的 TrueType 字体生成点阵数据,根据所选择的 TrueType 字体生成点阵数据

【 tulaoshi.com - C语言心得技巧 】

根据所选择的 TrueType 字体生成点阵数据

作者:胡峰

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

TrueType字体在Windows平台下的应用很多,但是涉及到具体的操作层面上中文资料还是很少,遇到了不少问题苦恼了一阵子。

1、通过 CFontDialog 进行字体选择,但是正常情况下得到的字体列表示当前系统中所有支持的字体,当然也包括其它一些非 TrueType 字体,要在 CFontDialog 的列表中剔出非 TrueType 的字体很简单,只需在配置 CFontDialog 时如下设置:

CFontDialog dlg;dlg.m_cf.Flags |= CF_TTONLY; //only enum TrueType 

2、要遍历所选择的字体中所包含的所有字符,这个我们不禁想到可以通过 .ttf文件的解析来完成,但是如何得到选择的字体所对应的 .ttf文件哪?同实际的操作,得知在CfontDialog中显示的字体的名称和所对应的.ttf文件不是一一对应的关系,例如:选择的字体为 Arial 那么在 System/Fonts/下却没有 Arial.ttf 的文件,在网上找了很多例子都不能百分百无误的实现,在 codeproject 中有一个例子 Sample 通过注册表的方法来查找,但是同样存在上面的问题。而且即使能够找到相对应的.ttf文件,要解析这个文件也很有困难,因为存在 ttc的问题(即:一个是一个ttf的集合,一个文件里面有可能定义几种 TrueType 字体),这样还要根据选择的字体然后在读取ttf文件的过程中进行比较,找到描述这种这种字体的部分,后来发现选择的字体有可能和文档中定义的TrueType字体名称不一致,因为有中文字体的存在,这一部分我并没有进行测试。因为在之后的解决过程找到了另外一种解决的方法。
 

DWORD CDC::GetFontData( DWORD dwTable, DWORD dwOffset, LPVOID lpData, DWORD cbData ) const; Remarks Retrieves font-metric information from a scalable font file. The information to retrieve is identified by specifying an offset into the font file and the length of the information to return. An application can sometimes use the GetFontData member function to save a TrueType font with a document. To do this, the application determines whether the font can be embedded and then retrieves the entire font file, specifying 0 for the dwTable, dwOffset, and cbData parameters. 

  通过上面的函数可以轻易的得到选入DC中的TrueType字体的 ttf文件中的数据,但是如果想得到整个的字体文件还是会存在ttc的问题,因为这个函数得到的数据是其中选择的那种字体的数据,但是对于各个数据段offset的定义却是针对于整个文档的,如果直接引用就会有问题,也没有找到其他更好的解决方法,但是却可以准确地得到关于其中任意一个Table的数据,刚刚好对于字符集中所包含的字符的定于存在于"cmap" Table中,问题解决了,如下:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
// Macro to pack a TrueType table name into a DWORD.#define     MAKETABLENAME(ch1, ch2, ch3, ch4) (    (((DWORD)(ch4)) << 24) |     (((DWORD)(ch3)) << 16) |     (((DWORD)(ch2)) << 8) |     ((DWORD)(ch1))  )DWORD tag = MAKETABLENAME( ''c'',''m'',''a'',''p'' );DWORD size = m_pFontDC->GetFontData(tag,0, NULL, 0);unsigned char *pBuffer = new unsigned char[size];m_pFontDC->GetFontData(tag,0,pBuffer,size);//do something with pBufferdelete[] pBuffer;
  其中具体的一些操作也可以参照 msdn 中的文章。之后就是解析ttf文件了,这要参考MS发布的TrueType Font规格书了,当然即使看懂了规格书,要自己做解析程序也是短时间难以完成的,还是让我们来找找有没有其他的已经有了的经验,在这里就要提到一个开源的项目了 fontforge 这是个日本人和台湾人维护的一个项目,可以支持多种字体进行解析和编辑,可以是个 Linux 下的程序,不过我们可以使用 Cygwin 来使这个程序在 Windows下运行起来,具体请参考 freefonts.oaka.org,但是这个程序太复杂太庞大了,我们一时半会还不能理出头绪来,幸好在 cle.linux.org看到 fontfoge 中有一个小工具叫做 showttf.c 可以简单的对于ttf文件进行解析,下载过来,进行编译,很有效。之后将其改进成可以只针对于“cmap”数据进行解析,并得到字体中支持字符的分段。
/*read a short(2 bytes) from a stream**/static int Getushort(unsigned char **ttf) {    unsigned char ch1 = **(ttf);        (*ttf)++;    unsigned char ch2 = **(ttf);        (*ttf)++;        return( (ch1<<8)|ch2 );}/*read a long(4 bytes) from a stream**/static int Getlong(unsigned char **ttf) {    unsigned char ch1 = **(ttf);        (*ttf)++;    unsigned char ch2 = **(ttf);        (*ttf)++;    unsigned char ch3 = **(ttf);        (*ttf)++;    unsigned char ch4 = **(ttf);        (
                        

来源:http://www.tulaoshi.com/n/20160129/1484135.html

延伸阅读
标签: 化妆
女孩们都想拥有最能衬托自己美丽的眉形,漂亮的眉形要根据脸型来选择: ①椭圆型脸。椭圆型脸是最标准的脸型,在设计眉形的时候尽量以眉间为主体,整个眉形会显得非常柔和,大致呈一条水平线,从而烘托出椭圆型脸的柔美。 ②圆型脸。圆脸适合上扬眉,使脸部相应拉长,眉峰的位置可以是靠外1/3处,眉峰形状不要太锐利,眉...
有时候我们需要根据combobox(listbox同样)的选择项的值进行处理,但是在delphi中的Combobox的item是一个TStrings类型的对象,我们无法象c#或java中那样从combobox的选项类中继承,创建一个我们需要的类来完成任务。但是仔细研究delphi的combobox对象发现了以下的解决方法: 新建一个类,存储我们需要的数据: TItemEx=class(TOb...
标签: Web开发
一,必须弄清楚最终需要的是什么 我们通过ASP或其他动态编程语言,最终需要的是XML格式的数据,这点和XML数据所在的文件载体无关,它可以是实实在在的XML文件,比如:http://www.dw8.cn/common/dw8.xml 。也可以为asp文档,比如:http://www.cnbruce.com/blog/rss2.asp 他们都是XML数据的体现,为了实现XML数据的动态,所以需要使用到动态编...
有时候我们可能在程序中需要动态去生成一些对象,但我们又不想写大量的case分支语句来实现,而是建一张表,根据类的名称或其他一些索引来生成类的实例——对象。如果你有这方面的需要,本文将会帮助你实现这一目的。在写正文之前首先要引进一个概念,类的变量(自己起的准确不准确无所谓,只大家明白就行啦)。这个类的变量并非我们平时看到的这...
标签: PHP
  背景知识: 简体中文国标字库(1981年订,中国大陆)。7445个字符,其中汉字6773个,包括一级汉字3755个,二级汉字3008个。采用2字节(16位二进制)编码。 区位码:国标GB2312规定,所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个”区”,每一列称为一个”位”,因此,这个方阵实际上组成了一个有94...

经验教程

543

收藏

63
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部