当前位置:文档之家› Windows矢量字体点阵数据提取的实现方法

Windows矢量字体点阵数据提取的实现方法

Windows矢量字体点阵数据提取的实现方法王小亮;王勇;汤永科;秦磊【摘要】Character display is widely used in embedded systems,especially for the embedded systems design without OS,getting lattice of character has played a crucial role in embedded paring with the general technique to get lattice of vector font through bit-map,this paper introduces a new method that can easily and quickly get lattice of any vector font installed in Windows system by using API of Windows OS.The program interface is simple and beautiful,and the function of the program is powerful and practical.%字符显示在嵌入式系统有着广泛的应用,尤其是在没有操作系统的嵌入式设计中,提取字符点阵数据已经成为嵌入式设计中的关键一步。

相比于一般通过位图方式来获取字符点阵数据,本文介绍了如何利用 Windows操作系统提供API函数提取矢量字体点阵数据的方法,程序可以方便快速提取Windows系统所安装的所有矢量字体的点阵数据。

程序界面简洁美观,功能强大,实用性强。

【期刊名称】《单片机与嵌入式系统应用》【年(卷),期】2014(000)006【总页数】4页(P30-33)【关键词】嵌入式系统;矢量字体;点阵;快速;API【作者】王小亮;王勇;汤永科;秦磊【作者单位】四川大学电子信息学院,成都 610044;四川大学电子信息学院,成都 610044;四川大学电子信息学院,成都 610044;四川大学电气信息学院【正文语种】中文【中图分类】TP399随着显示技术日新月异的发展,各种性能的显示器越来越广泛地运用于嵌入式产品中。

用户界面友好已经成为一个产品能否获得成功至关重要的因素。

在Windows 操作系统中,系统本身为用户提供了各种丰富的矢量字体,同时用户也可以通过简单地安装相应的字体文件,然后在编辑软件中点击相应的按键就可以使用各种矢量字体。

因为PC系统中,可以非常方便和快捷地获取各种矢量字体,所以在嵌入式系统开发设计中,我们会思考如何利用Windows系统所提供的丰富的矢量字体来获取所需要的点阵数据。

本文利用Windows 提供的API函数,设计实现了矢量字体字模提取的工具软件。

在纸上写字时,我们需要在纸上把字符的所有的点都画出来,这样就完成了字符的书写。

计算机显示字符也是通过把字符轮廓中相应的点阵数据显示在显示器上,从而实现计算机“书写”功能。

计算机所显示的字符点阵数据是通过一定的方式预先储存在计算机系统的文件中,当操作系统需要显示字符时,通过相应程序去查找对应的点阵数据,然后达到显示字符的效果。

矢量字体(vector font)中每一个字形是通过数学曲线来描述的,它包含了字形边界上的关键点,连线的导数信息等,字体的渲染引擎通过读取这些数学矢量,然后进行一定的数学运算来进行渲染。

这类字体的优点是,字体实际尺寸可以任意缩放而不变形、变色。

矢量字体主要包括Type1、 TrueType、OpenType等几类,这些格式都是与平台无关的。

由于矢量字体具有以上各种优势,所以在嵌入式产品的人机界面设计中有着广泛的应用。

在Windows 系统当中提取矢量字体的字模,一般有两种方法。

一种方法,通过截取字体在当前Windows系统DC设备当中的位图,然后根据位图的像素元素提取相应的点阵数据。

当字符数目比较多的时候,这种方法的缺点是提取速度慢,需要通过程序处理大量的图片像素数据来获取字符点阵。

这种方法无论是从时间、空间还是内存空间来看,对系统的消耗都是非常大的。

同时,如果用户输入的字符数量非常大时,软件界面需要提供比较大的输入区以方便用户输入,所以这种提取方式对于程序输入界面有比较高的要求,且不易支持直接从文本文件直接输入字符。

另一种方法是利用Windows系统的API函数GetGlyphOutline,该函数可以方便快捷地提取矢量字体字符点阵数据,并且可以很好地支持从文本文件中读取字符。

面对大量字符数据输入时,获取点阵数据所需要的时间量也很少。

GetGlyphOutline函数声明如下:DWORD GetGlyphOutline(HDC hdc,);GetGlyphOutline函数是Windows系统的API函数,在使用VC++开发时,这个函数被封装在DC类中,是DC类的一个成员函数。

当应用程序调用GetGlyphOutline 函数时,该函数可以通过LPGLYPHMETRIC结构体指针返回所需的字符点阵数据所占的矩形区域信息。

该函数所得到的点阵数据是gmBlackBoxX与gmBlackBoxY所组成的最小矩形区域的点阵数据,如图1所示。

实际应用中,所需要显示的字符点阵数据却是gmCellIncX与gmCellIncY所组成的大矩形区域内的点阵数据,所以调用GetGlyphOutline所得到的字符的点阵数据时,还需要把最小矩形以外的边框区域加上,这需要通过相应的矩阵变换把最小矩形的点阵数据区平移到以gmCellIncX与gmCellIncY所组成的大矩形区域的中间位置。

在Windows 操作系统当中实践表明,GetGlyphOutlinep这个函数返回的结构体LPGLYPHMETRICS中的gmCellIncY这个数值返回是0,这是操作系统版本本身的原因,因此需要通过另外的方法来获取。

我们采用GetTextExtent(CString,int)和GetTextMetrics(TEXTMETRIC *tm),通过以上两个函数可以获取字符的宽度与高度信息,然后通过相应矩阵变换的变换,就可以得到所需的字符字模点阵数据。

GetGlyphOutline 函数获取的字符点阵数据的宽度是4字节对齐,所以要做4字节对齐处理。

对于宽度不是以8位对齐的字符数据,应该在补足8位后,再做4字节对齐处理。

获取字符点阵数据的程序如下:CString str ( “华”); //字符CDC dc; //CDC 类,有GetGlyphOutline方法dc.CreateDC(_T("DISPLAY"), NULL, NULL, NULL);CFont *poldfont=dc.SelectObject(&m_font); //字体设置TEXTMETRIC tm;GLYPHMETRICS pGL;MAT2 mat2 = {{0, 1},{0, 0},{0, 0},{0, 1}}; //转换矩阵dc.GetTextMetrics(&tm);int bitWidth =tm.tmAveCharWidth;int ch = str.GetAt(0);int len =dc.GetGlyphOutline(ch, GGO_BITMAP, &pGL, 0, NULL, &mat2); CSize cs = pDC->GetTextExtent(str,1);int widthEx = cs.cx;bitWidth = widthEx;if(bitWidth %8 ==0){bitWidth = bitWidth /8;}else{bitWidth = bitWidth /8+1;}int boxXByteWidth = ALIGN(pGL.gmBlackBoxX, 4);int FontOffY = tm.tmAscent - pGL.gmptGlyphOrigin.y;unsigned char *pBuf = new unsigned char[bufSize];if(pBuf != NULL){memset(pBuf, 0, bufSize);if(len > 0){unsigned char *pSrc = new unsigned char [len];unsigned char *pDest = (unsigned char *)pBuf;dc.GetGlyphOutline(ch, GGO_BITMAP, &pGL, len, pSrc, &mat2);for(int i = 0; i < len / boxXByteWidth; i++){//copy databuf to pDestmemcpy(pDest + i * (bitWidth /8), pSrc + i * boxXByteWidth, boxXByteWidth);}//转换矩阵,把GetGlyphOutline得到的点阵转换成 //含有边框的点阵数据MartixCovert(pDest,bitWidth, bitHeigh ,FontOffX, FontOffY);}}dc.SelectObject(poldfont);dc.DeleteDC();delete []pSrc;delete []pDest;通过上文分析已经得到单个字符的点阵数据,然而在实际应用当中,获取单个字符的点阵数据是没有实用性的,所以在上文的基础上,利用VC++开发工具,开发了实用的字模点阵数据提取软件。

软件支持两种字符输入方式,一是通过VC++中的CEdit类来接收用户直接输入的字符,二是利用CStdioFile类来实现文本文件的输入;利用CString类对通过以上两种方式输入获取字符进行串化处理(用CString保存),同时利用CFont类实现对用户对字体格式修改操作,然后对所得到的字符串做空格过滤处理;最后根据上文介绍的方法获取字符串中每一个字符的点阵数据。

对于获取到的点阵数据作输出格式化处理,为其加上相应的数据信息头,并用“{}”框起,结尾处加上“;”,以实现符合C语言中变量声明方式,这样在实际应用当中只需修改文本文件的后缀名,在文件中加上相关的变量声明就可以在直接在实现工程中应用。

为了把软件开发成为通用性强的应用软件,本软件在提取字符点阵数据的基础上增加了提取图像像素数点阵的功能。

这个功能是以图像文件操作为基础,可以支持PNG、BMP、JPEG等图像文件输入,提供用户创建图像文件的功能,同时支持用户的绘图操作。

相关主题