源:windows矢量字体点阵数据的提取

问题参考:windows api 获取字库点阵的问题

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矢量字体点阵数据的提取(转)的更多相关文章

  1. 在 Ubuntu 14.10 中借用 Windows 的字体

    在前一篇随笔中,我详细讨论了字体的分类及用途,也以 Fedora 20 为例,展示了字体配置的思路和方法.我在配置 Fedora 20 系统字体的时候,采用的是一种釜底抽薪的方法,完全抛开了系统原有的 ...

  2. VB6基本数据库应用(四):数据的提取,新增和修改

    列的第四篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/9474661 数据的提取,新增和修改 由于在写第三章的时候没有充分考虑这一章 ...

  3. Linux应用环境实战05:在Ubuntu 14.10中借用Windows的字体 (转)

    阅读目录 设置系统字体 安装微软的英文字体 查看系统的配置文件 借用Windows的字体 编写配置文件 在前一篇随笔中,我详细讨论了字体的分类及用途,也以Fedora 20为例,展示了字体配置的思路和 ...

  4. Delphi中建立指定大小字体和读取该字体点阵信息的函数(转)

    源:Delphi中建立指定大小字体和读取该字体点阵信息的函数 Delphi中建立指定大小字体和读取该字体点阵信息的函数 作者:Thermometer Email:  webmaster@daheng- ...

  5. sublime在混杂的log数据中提取你想要的内容

    前几天因为同事一个sql写的有问题,导致我这边处理mysql入库出现数据丢失,没什么办法啊,为了回复数据,只能去翻前两天的log了,但是怎么从十几个几十兆的文件中找到我们需要的数据然后提取出来呢,我的 ...

  6. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  7. Gprinter热敏打印机光栅位图点阵数据解析工具

    最近参与的项目有一个需求,解析佳博热敏打印机的光栅位图点阵数据并保存为图片文件.数据是通过Bus Hound抓取的,如下图所示. 其中1b 40为初始化打印机的指令,对应的ASCII码为ESC @,1 ...

  8. UWP 矢量字体图标(iconfont)使用

    本文使用 阿里巴巴开源字体: 选择矢量字体图标: 查看或编辑 Unicode编码 或字体名称 下载到本地,添加到uwp项目 代码中写法 Text:Unicode编码 FontFamily:文件路径#字 ...

  9. 从Wireshark监听的数据中提取需要的数据

    最近,需要将wireshark监听的数据进行提取,分两步:首先,应该得出wireshark的数据包吧,在图形化界面中可以非常直观的将监听数据进行存储,但是这样需要手动操作非常麻烦,而且容易出错(随着处 ...

随机推荐

  1. perl的USE和require

    来源: http://www.cnblogs.com/itech/archive/2010/11/22/1884345.html 相同: 都可以用来引用module(.PM). 不同: 1) 区别在于 ...

  2. (UE4) 动态加载DLL

    目前还没有实现,实在搞不懂为什么,大概代码如下: //------------------------------------------------------------------------- ...

  3. java设计模式案例详解:观察者模式

    观察者模式的应用场景: 1. 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变. 2. 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节. 举个例子说明,这个例子讲 ...

  4. merge 语句的语法

    /*Merge into 详细介绍 MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句. 通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询, 连接条 ...

  5. HALF<水题>

    题意: 找出n/d=0.5的所有数.输入:test,x(代表n的位数,1<=x<=4).并且n和d的每一个位数不能有重复,也不能是0. 输入: 1 1 输出: the form 1/2 = ...

  6. C++的精髓——虚函数

    虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 引入原 ...

  7. Chapter 1 First Sight——17

    Once I got around the cafeteria, building three was easy to spot. 我一走出自助餐厅,很容易看见建筑三. A large black & ...

  8. MySQL 建表

    SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for ` ...

  9. Base64笔记

    1. 昨天的<MIME笔记>中提到,MIME主要使用两种编码转换方式----Quoted-printable和Base64----将8位的非英语字符转化为7位的ASCII字符. 虽然这样的 ...

  10. STL笔记之【map之移除元素】

    //---------------------------------------------------------// 移除map中满足条件的元素//----------------------- ...