初探freetype字体库

62 篇文章 0 订阅
43 篇文章 0 订阅

文字的显示依赖于字体字库,大致的字体字库分为点阵字库、笔画字库和轮廓字库。

点阵字库:缺点比较明显,缩放存在锯齿,渲染旋转等操作相对复杂,且效果不理想,先大多用在嵌入式行业(基本抛弃),常见格式有bdf,pcf,fnt,hbf,hzf等。

笔画字体:不讨论。

轮廓字体:即矢量字体,利用字体轮廓及填充实现字体显示,优势明显,渲染缩放较容易,但效率相对低些(相对于嵌入式)

 

简单来说,freetype为字体字库提供了一套解决方案,支持文字字体渲染等操作,主要还是其为C语言编写,跨平台,为很多不支持矢量字体格式的嵌入式系统提供使用嵌入式字体的可能,且效率不低。

基本流程为:
加载字体字库文件-> 查找待显示的文字索引-> 渲染操作(若反走样处理)->处理为位图数据->显示

freetype官网http://freetype.sourceforge.net/index2.html

下面为在XP下显示中文字体的实例,在官方下载源码,在..\freetype-2.4.2\builds\win32\vc2008\下打开工程,编译为链接库,新建VS2008的MFC程序,加载freetype242.lib库。

 

简单考虑,直接在MFC中的draw函数中画出一个中文汉字。便于显示,使用GDI+画出汉字,因此首先对GDI+进行初始化等操作(GDI+的相关知识不讨论,不清楚可以留言或索取GDI+文档,网上也可以搜搜)

在view.h中添加头文件声明

 

1
2
#include <ft2build.h>
#include FT_FREETYPE_H

 

 

在view.h中添加成员变量

 

1
2
3
public :
     FT_Library library;
     FT_Face face;

 

 

在view.cpp的构造函数中添加

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 初始化库
bool  bError = FT_Init_FreeType(&library);
if  (!bError)
{
// 是否初始化成功
}
// 加载一个字库文件,这里为黑体中文字库
bError = FT_New_Face(library,
"C:\\WINDOWS\\Fonts\\simhei.ttf" ,
0, &face);
if  (bError == FT_Err_Unknown_File_Format)
{
// 表示可以打开和读此文件,但不支持此字体格式
}
else  if  (bError)
{
// 其他错误
}
// 设定为UNICODE,默认也是
  FT_Select_Charmap(face,FT_ENCODING_UNICODE);
  // 设定字体字符宽高和分辨率
bError = FT_Set_Char_Size(face, 0, 16*64, 300, 300);

 

 

在::OnDraw(CDC* pDC)中添加代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool  bError;
wchar_t  wChar= _T( '博' );
// 查找‘好’的字符索引
FT_UInt glyph_index = FT_Get_Char_Index(face, wChar);
// 装载字型图像到字形槽
bError = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
 
 
// 转换为位图数据
if  (face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
{
// 第二个参数为渲染模式,这里渲染为1位位图(黑白位图),若为FT_RENDER_MODE_NORMAL则渲染为256级灰度图
bError = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
}

 

 

这里便可以通过face->glyph->bitmap获得字体“博”的位图数据了,bitmap中存放了如位图的宽高、色深,调色板等信息,便可以通过GDI+绘制该图像了 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//创建位位图
BITMAPINFO bmpinfo = {0};
// 初始化位图结构体
bmpinfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmpinfo.bmiHeader.biWidth = face->glyph->bitmap.width;
bmpinfo.bmiHeader.biHeight = face->glyph->bitmap.rows;
bmpinfo.bmiHeader.biBitCount = 1; // 与渲染模式有关,详见FreeType API手册的FT_Bitmap部分说明
bmpinfo.bmiHeader.biClrImportant = 0;
bmpinfo.bmiHeader.biClrUsed = 0;
bmpinfo.bmiHeader.biCompression = BI_RGB;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biSizeImage = 0;
 
 
// 创建内存位图
unsigned char  *pvBits = new  unsigned char [10000];
HBITMAP  hBitmap =CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, ( void  ** )&pvBits, NULL, 0 );
 
int  iLineBytes = (bmpinfo.bmiHeader.biWidth + 7) / 8;
for  ( int  i = 0; i != bmpinfo.bmiHeader.biHeight; ++i)
{
memcpy (pvBits + i * iLineBytes, face->glyph->bitmap.buffer + i * iLineBytes, iLineBytes);
}
 
Bitmap *pBitmap = Bitmap::FromHBITMAP(hBitmap, NULL);
Graphics graphic(pDC->m_hDC);
graphic.DrawImage(pBitmap, Point(20, 150));

 

 

这部分代码不多解释,只是显示位图数据,这里face->glyph->bitmap是没有调色板的1位位图,源于使用FT_RENDER_MODE_MONO渲染模式

 

显示预览

1
 
1
这里字体倒置与位图坐标系有关,只要简单处理即可,不讨论。

简单的描述一下freetype的使用流程,更详细的函数说明及流程请参阅“freetype2开发入门”, 网上有此文档,感兴趣可以看看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这份文档提供了FreeType 2函数库设计与实现的细节。本文档的目标是让开发人员更好的理解FreeType 2是如何组织的,并让他们扩充、定制和调试它。 首先,我们先了解这个库的目的,也就是说,为什么会写这个库: * 它让客户应用程序方便的访问字体文件,无论字体文件存储在哪里,并且与字体格式无关。 * 方便的提取全局字体数据,这些数据在平常的字体格式中普遍存在。(例如:全局度量标准,字符编码/字符映射表,等等) * 方便的提取某个字符的字形数据(度量标准,图像,名字,其他任何东西) * 访问字体格式特定的功能(例如,SFNT表,多重控制,OpenType轮廓表) Freetype 2的设计也受如下要求很大的影响: * 高可移植性。这个库必须可以运行在任何环境中。这个要求引入了一些非常激烈的选择,这些是FreeType2的低级系统界面的一部分。 * 可扩展性。新特性应该可以在极少改动库基础代码的前提下添加。这个要求引入了非常简单的设计:几乎所有操作都是以模块的形式提供的。 * 可定制。它应该能够很容易建立一个只包含某个特定项目所需的特性的版本。当你需要集成它到一个嵌入式图形库的字体服务器中时,这是非常重要的。 * 简洁高效。这个库的主要目标是只有很少cpu和内存资源的嵌入式系统。 这份文档的其他部分分为几个部分。首先,一些章节介绍了库的基本设计以及Freetype 2内部对象/数据的管理。 接下来的章节专注于库的定制和与这个话题相关的系统特定的界面,如何写你自己的模块和如何按需裁减库初始化和编译。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值