windows矢量字体点阵数据的提取(转)
1.提取原理
在windows系统当中提取矢量字体的字模有很多方法,下面介绍一种利用GetGlyphOutline来实现字模点数数据的提取。
GetGlyphOutline是windows系统的API函数,利用这个函数,可以方便快捷提取矢量字体字符点阵数据,并且可以很好的支持从文本文件中读取字符。面对用大量字符数据输入时,获取点阵数据所需要的时间量也是很少。
GetGlyphOutline函数声明如下:
DWORD GetGlyphOutline(
HDC hdc, // handle to DC
UINT uChar, // character to query
UINT uFormat, // data format
LPGLYPHMETRICS lpgm, // glyph metrics
DWORD cbBuffer, // size of data buffer
LPVOID lpvBuffer, // data buffer
CONST MAT2 *lpmat2 // transformation matrix
);
GetGlyphOutline函数是windows系统的API函数,在使用VC++开发时,这个函数被封装在DC类中,是DC类的一个成员函数。
2.字符点阵数据提取的实现
当应用程序调用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;//这是个结构体这个结构体包含了字体的信息,
GLYPHMETRICSpGL;//这个结构体包含了一个基本字符单元的位置与方向的信息
MAT2 mat2 = {{,},{, },{, },{, }}; //转换矩阵
dc.GetTextMetrics(&tm); //获取当前选择字体宽度与高度
int bitWidth=tm.tmAveCharWidth;//字符宽度的平均值
int bitHeigh =tm.tmHeight;//字符高度
int ch = str.GetAt();
int len =dc.GetGlyphOutline(ch,GGO_BITMAP, &pGL, , NULL, &mat2);//所得//到数据缓存区的大小
CSize cs = pDC->GetTextExtent(str,);//重新获得字符的宽度,修正值
int widthEx =cs.cx;
bitWidth =widthEx;
if(bitWidth %==)
{
bitWidth= bitWidth /; //字符宽度8位对齐,不足8位,补齐8位
}
else
{
bitWidth= bitWidth /+;
}
int boxXByteWidth = ALIGN(pGL.gmBlackBoxX, );// 最小矩形宽度,4字节对齐
int FontOffY = tm.tmAscent - pGL.gmptGlyphOrigin.y;//获取Y方向偏移
int FontOffX = pGL.gmptGlyphOrigin.x < ? :pGL.gmptGlyphOrigin.x;//获取X方向偏移
int bufSize = bitWidth* bitHeigh;//字符点阵数据大小
unsigned char *pBuf =new unsigned char[bufSize];//databuf
if(pBuf != NULL)
{
memset(pBuf, , bufSize);
if(len > )
{
unsigned char *pSrc = newunsigned char [len];
unsigned char *pDest =(unsigned char *)pBuf;
dc.GetGlyphOutline(ch, GGO_BITMAP,&pGL, len, pSrc, &mat2);//得到点阵数据
for(int i = ; i < len / boxXByteWidth;i++)
{ //copy databuf to pDest
memcpy(pDest + i * (bitWidth/), pSrc + i * boxXByteWidth, boxXByteWidth);
}
//转换矩阵,把GetGlyphOutline得到的点阵转换成含有边框的点阵数据
MartixCovert(pDest,bitWidth,bitHeigh ,FontOffX, FontOffY);
}
}
dc.SelectObject(poldfont);
dc.DeleteDC();
delete []pSrc;
delete []pDest;
下面是点阵数据的显示效果
windows矢量字体点阵数据的提取(转)的更多相关文章
- 在 Ubuntu 14.10 中借用 Windows 的字体
在前一篇随笔中,我详细讨论了字体的分类及用途,也以 Fedora 20 为例,展示了字体配置的思路和方法.我在配置 Fedora 20 系统字体的时候,采用的是一种釜底抽薪的方法,完全抛开了系统原有的 ...
- VB6基本数据库应用(四):数据的提取,新增和修改
列的第四篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/9474661 数据的提取,新增和修改 由于在写第三章的时候没有充分考虑这一章 ...
- Linux应用环境实战05:在Ubuntu 14.10中借用Windows的字体 (转)
阅读目录 设置系统字体 安装微软的英文字体 查看系统的配置文件 借用Windows的字体 编写配置文件 在前一篇随笔中,我详细讨论了字体的分类及用途,也以Fedora 20为例,展示了字体配置的思路和 ...
- Delphi中建立指定大小字体和读取该字体点阵信息的函数(转)
源:Delphi中建立指定大小字体和读取该字体点阵信息的函数 Delphi中建立指定大小字体和读取该字体点阵信息的函数 作者:Thermometer Email: webmaster@daheng- ...
- sublime在混杂的log数据中提取你想要的内容
前几天因为同事一个sql写的有问题,导致我这边处理mysql入库出现数据丢失,没什么办法啊,为了回复数据,只能去翻前两天的log了,但是怎么从十几个几十兆的文件中找到我们需要的数据然后提取出来呢,我的 ...
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...
- Gprinter热敏打印机光栅位图点阵数据解析工具
最近参与的项目有一个需求,解析佳博热敏打印机的光栅位图点阵数据并保存为图片文件.数据是通过Bus Hound抓取的,如下图所示. 其中1b 40为初始化打印机的指令,对应的ASCII码为ESC @,1 ...
- UWP 矢量字体图标(iconfont)使用
本文使用 阿里巴巴开源字体: 选择矢量字体图标: 查看或编辑 Unicode编码 或字体名称 下载到本地,添加到uwp项目 代码中写法 Text:Unicode编码 FontFamily:文件路径#字 ...
- 从Wireshark监听的数据中提取需要的数据
最近,需要将wireshark监听的数据进行提取,分两步:首先,应该得出wireshark的数据包吧,在图形化界面中可以非常直观的将监听数据进行存储,但是这样需要手动操作非常麻烦,而且容易出错(随着处 ...
随机推荐
- Linux 配置tomcat遇见的若干问题
1.提示catalina.sh缺失 原因:未对bin目录下的.sh文件授权 执行:chmod +x bin/*.sh即可 2.正常启动Tomcat 但是外界无法访问 Linux防火墙原因,进入到 et ...
- hibernate5 中的schemaExport
hibernate5中的schemaExport与之前版本中的用法有所不同,具体用法如下: ServiceRegistry serviceRegistry = new StandardServiceR ...
- 使用VS软件打开网站在浏览器浏览的方法
1.用VS软件打开网站之后,先检查网站是否使用IIS Express开发 2.若不是,则切换成使用IIS Express开发 3.检查项目使用的托管管道模式设置为经典模式了没有 4.最后选择“在浏览器 ...
- Java学习笔记之I/O
package com.chinasofti.javase20160819; import java.io.BufferedReader; import java.io.BufferedWriter; ...
- ubuntu14下python环境的配置
1.安装build依赖包(一些包需要用pip编译) sudo apt-get install python-dev 2.安装pip包管理工具 sudo apt-get install python-p ...
- UVA 10308 Roads in the North
input u1 v1 w1 u2 v2 w2 ... un vn wn 1<=vi,ui<=n+1 /n output 距离最远的两个点的距离 做法:一颗全连通且只有一条路从一个顶点到达 ...
- dirname(_file_) DIRECTORY_SEPARATOR
<?php echo __FILE__ ; // 取得当前文件的绝对地址,结果:D:\www\test.php echo dirname(__FILE__); // 取得当前文件所在的绝对目录, ...
- keyboardWillChangeFrameNotification 引发的思考 是的 思考了很久终于出结果
func keyboardWillChangeFrameNotification(note: NSNotification) { // TODO 添加键盘弹出的事件 let userinfo = no ...
- Tiny210编译和烧写u-boot步骤
当有多个交叉编译器是,不方便设置环境变量时,可以在编译命令中指定交叉编译器,具体如下: make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/ ...
- HDU 4685 Prince and Princess(二分匹配+强联通分量)
题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...