FreeType编译及使用心得收藏

 

FreeType是一款字体服务库,它支持多种字体,并且提供高效,高质量的文字。

freetype相关介绍见:http://blog.csdn.net/ganxingming/archive/2006/06/05/774796.aspx

1, 编译FreeType 解压后进入./include/freetype,复制config到当前文件夹,随便去个什么名,这里我用custom_config

然后进入 ./builds/win32/visualc 这里是vs工程,因为FreeType的支持相当广泛,有很多我们不需要东西,因此需要重新编译FreeType。 而刚才我们复制的文件夹中,就是FreeType的可定制文件

打开工程后,将你刚才复制的文件夹加入到工程中,即custom_config 然后打开ft2build.h 可以看到这里包含了一个文件, #include <freetype/config/ftheader.h> 这个文件就是用于定制FreeType的主要文件,我们要做的就是创建自己的定制文件,将其替代这个文件,将其改成 #include <freetype/custom_config/ftheader.h> custom_config是你自己的文件夹哈

然后进入custom_config/ftheader.h 修改这几行 #define FT_CONFIG_CONFIG_H    <freetype/config/ftconfig.h> #define FT_CONFIG_STANDARD_LIBRARY_H    <freetype/config/ftstdlib.h> #define FT_CONFIG_OPTIONS_H    <freetype/config/ftoption.h> #define FT_CONFIG_MODULES_H    <freetype/config/ftmodule.h> 改成 #define FT_CONFIG_CONFIG_H    <freetype/custom_config/ftconfig.h> #define FT_CONFIG_STANDARD_LIBRARY_H    <freetype/custom_config/ftstdlib.h> #define FT_CONFIG_OPTIONS_H    <freetype/custom_config/ftoption.h> #define FT_CONFIG_MODULES_H    <freetype/custom_config/ftmodule.h>

接着进入custom_config/ftmodule.h 这个文件是FreeType的模块注册,我把它改成了 /*FT_USE_MODULE(autofit_module_class)*/ FT_USE_MODULE(tt_driver_class) /*FT_USE_MODULE(t1_driver_class)*/ /*FT_USE_MODULE(cff_driver_class)*/ /*FT_USE_MODULE(t1cid_driver_class)*/ /*FT_USE_MODULE(pfr_driver_class)*/ /*FT_USE_MODULE(t42_driver_class)*/ /*FT_USE_MODULE(winfnt_driver_class)*/ /*FT_USE_MODULE(pcf_driver_class)*/ /*FT_USE_MODULE(psaux_module_class)*/ /*FT_USE_MODULE(psnames_module_class)*/ /*FT_USE_MODULE(pshinter_module_class)*/ /*FT_USE_MODULE(ft_raster1_renderer_class)*/ FT_USE_MODULE(sfnt_module_class) FT_USE_MODULE(ft_smooth_renderer_class) /*FT_USE_MODULE(ft_smooth_lcd_renderer_class)*/ /*FT_USE_MODULE(ft_smooth_lcdv_renderer_class)*/ /*FT_USE_MODULE(bdf_driver_class)*/ 只留下了3个模块

好,现在FreeType定制完毕了,但是还有个问题,FreeType是编译的静态链接库,我们一般是使用动态链接库的, 因此需要将其修改成动态链接库。

进入custom_config/ftconfig.h,将 #ifndef FT_EXPORT

#ifdef __cplusplus #define FT_EXPORT( x )    extern "C"    x #else #define FT_EXPORT( x )    extern    x #endif

改成

#ifdef    DLL_EXPORT #undef    DLL_EXPORT #define DLL_EXPORT    __declspec(dllexport) #else #define DLL_EXPORT    __declspec(dllimport) #endif /* !DLL_EXPORT */

#ifndef FT_EXPORT

#ifdef __cplusplus #define FT_EXPORT( x ) extern "C" DLL_EXPORT x #else #define FT_EXPORT( x ) extern DLL_EXPORT x #endif

接下来修改工程,进入工程属性的Release Multithreaded配置,我们编译多线程版本哈 进入常规,修改配置类型为动态库 进入C/C++ -> 预处理器,在预处理器定义中加入DLL_EXPORT

好了,现在我们可以开始编译了。编译成功后的目录在objs/release_mt,现在可以拷贝 freetype.dll,freetype.lib和整个include文件夹,到我们的工程中了

2, 使用FreeType 这里就请大家参考帖子 http://www.unixresources.net/lin ... 0/59/21/592188.html 里面有详细的介绍。

下面,我说一下自己使用FreeType的心得 1, 得到字符的正确绘制位置

首先在创建好FTFace,Freetype推荐使用基线作为绘制基准,但是通常都是设置字符左上角的位置开始绘制。需要获

得基线到字符轮廓最高点的距离,这个信息放在

Ascender = FTFace->size->metrics.ascender    >> 6; // 基线到字符轮廓最高点的距离, 由于是26.6的定点数,

因此获取整数部分需要除以64

然后每个字符的高度是不同的,Freetype生成的bitmap一般刚刚好包围到字符,比如a和l的bitmap图高度是不同的。

因此还需要获得每个字符的偏移宽度和高度,这两个信息放在

bitmap_left = FTFace->glyph->bitmap_left;    // 字符距离左边界的距离 bitmap_top = FTFace->glyph->bitmap_top; // 字符最高点距离基线的距离

好了,现在假设要在(posx, posy)处绘制字符,(charposx, charposy)表示字符的正确绘制位置

charposx = posx + bitmap_left; charposy = posy + Ascender - bitmap_top;

2,行距 字符轮廓最大高度放在 FTFace->size->metrics.height         // 字符轮廓最大高度, 26.6定点数 但是我实测发现,这个高度太高了点,所以我一般是这样用的

Descender = FTFace->size->metrics.descender >> 6;    // // 基线到字符轮廓最低点的距离 FontHeight    = ((FTFace->size->metrics.height >> 6) + Ascender + Descender) / 2;

然后还可以在FontHeight上加上一个固定高度,比如1或2

3,字符颜色 Freetype生成的图是8bit灰度图(也有别的,不过8bit好看些),文字部分为白色,背景为黑色。 这就有个麻烦,一般字体都是黑的,那好如果把字体颜色取反,就黑的变白的,白的变黑的了。 可是呢,要加上颜色怎么办?这就是Freetype的文字是白色的原因,因为是8bit灰度图,因此不是黑色或白色的地方

,颜色就成了一个比例因子,只需将其与想要设置的颜色相乘再除以256即可,比如灰度图中某点的颜色是156,想要

设置的颜色是RGB(127, 42, 186),那么实际的颜色是

(127 * 156 >> 8, 42 * 156 >> 8, 186 * 156 >> 8)

回到之前说的,如果将黑的变白的,白的变黑的,那么比例因子就要再取反一次,麻烦了。 而且,如果字体被设置过颜色后,灰度图的比例因子效果就丧失了,不能再被设置成其他颜色了(重新获取灰度图就要

花多余的时间了)。 解决方法是,把8bit灰度图保存在alpha通道中。如果想设置颜色就从alpha通道中获取灰度值即可。

4,把字符变的好看些 上面把灰度图保存在alpha通道中了,如果你的驱动支持alpha混合,那么恭喜你了,字符能和背景混合。 不错,灰度图还兼有alpha功能,如果想好看些就做alpha混合吧。 我的驱动不支持alpha混合,只好自己混合了。

源自 http://hi.baidu.com/yq_sun2008/blog/item/cbc18bfb5a52c71e6c22eb04.html

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

点阵字库:缺点比较明显,缩放存在锯齿,渲染旋转等操作相对复杂,且效果不理想,先大多用在嵌入式行业(基本抛弃),常见格式有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 #include <ft2build.h>
2 #include FT_FREETYPE_H

在view.h中添加成员变量

1 public :
2      FT_Library library;
3      FT_Face face;

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

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

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

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

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

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

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

显示预览

freetype的更多相关文章

  1. C#+OpenGL+FreeType显示3D文字(1) - 从TTF文件导出字形贴图

    C#+OpenGL+FreeType显示3D文字(1) - 从TTF文件导出字形贴图 +BIT祝威+悄悄在此留下版了个权的信息说: 最近需要用OpenGL绘制文字,这是个很费时费力的事.一般的思路就是 ...

  2. C#+OpenGL+FreeType显示3D文字(3) - 用PointSprite绘制文字

    C#+OpenGL+FreeType显示3D文字(3) - 用PointSprite绘制文字 上一篇实现了把文字绘制到OpenGL窗口,但实质上只是把含有文字的贴图贴到矩形模型上.本篇我们介绍用Poi ...

  3. C#+OpenGL+FreeType显示3D文字(2) - 用GLSL+VBO绘制文字

    C#+OpenGL+FreeType显示3D文字(2) - 用GLSL+VBO绘制文字 +BIT祝威+悄悄在此留下版了个权的信息说: 上一篇得到了字形贴图及其位置字典(可导出为XML).本篇就利用此贴 ...

  4. NeHe OpenGL教程 第四十三课:FreeType库

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. mac升级yosemite后安装gd的freetype扩展

    Mac升级系统到 Yosemite 10.10,对于各位Coder来说,还是需要一些时间来折腾的! @星空之下 同学反映 PHPCMS 的验证码图片不能正常显示,反馈该验证码需要GD库支持FreeTy ...

  6. Bug: freetype/fterrors.h: No such file or directory

    Bug描述: 安装PIL过程中出现题目中的错误信息,具体如下:

  7. 使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果

    前言: Freetype是一个跨平台.开源的字体渲染器,网上很多文章介绍,本人就不啰嗦了.本文重点在于实现文章标题所属的各种效果,不是Freetype的基本使用方法介绍文档,所以对于Freetype不 ...

  8. 基于Qt的FreeType字体轮廓解析

    一.本文目的 以前的文档中.详细的介绍了FreeType开源字体引擎库的基础知识.基本用法.但并未详细的阐明在TurboCG中.是如何解析出一个文字的轮廓的,本文集中阐述.怎么样使用FreeType开 ...

  9. Configure: error: freetype.h not found. 的解决办法

    出现 Configure: error: freetype.h not found. 的解决办法 CentOS yum install freetype-devel Debian apt-get in ...

  10. FreeType in OpenCASCADE

    FreeType in OpenCASCADE eryar@163.com Abstract. FreeType is required for text display in the 3D view ...

随机推荐

  1. Failed to create the Java Virtual Machine

    启动Zend Studio时出现Failed to create the Java VIrtual Machine 解决办法如下.打开安装目录下的ZendStudio.ini配置文件,作如下修改: 说 ...

  2. Temp权限导致Win10安装程序失败提示2502/2503错误

    有Win10用户在安装程序时遇到了安装失败错误代码2502/2503的问题.如图: 其原因是Windows Installer安装程序需要当前用户具有C:\Windows\Temp目录的完全控制权限, ...

  3. 【58沈剑架构系列】为什么说要搞定微服务架构,先搞定RPC框架?

    第一章聊了[“为什么要进行服务化,服务化究竟解决什么问题”] 第二章聊了[“微服务的服务粒度选型”] 今天开始聊一些微服务的实践,第一块,RPC框架的原理及实践,为什么说要搞定微服务架构,先搞定RPC ...

  4. day5模块学习--sys模块

    sys模块 sys模块是处理与系统相关的模块,sys(system),下面来看看sys模块常用的方法: 1.sys.argv         #命令行参数list,第一个元素是程序本身路径 2.sys ...

  5. 【Codeforces】113 D. Museum

    题解 我们设\(f(i,j)\)是\((i,j)\)这个点期望被经过多少次 我们可以列出方程组来消元,由于终点只会被经过0次或者1次,期望就是概率 对于起点的话我们期望经过次数多加一个1 复杂度\(O ...

  6. python之web框架(3):WSGI之web应用完善

    python之web框架(3):WSGI之web应用完善 1.上篇的web框架太low,只能实现回应固定页面.现在将它进行完善.首先将wsgi和web服务器进行分离,并给予它回复静态页面的能力. we ...

  7. Gitlab-通过API管理项目

    Gitlab有一个非常强大的API,几乎可以通过API管理在Gitlab服务器中的所有项目. 在这里我们只是测试终端点的API, 因此我们需要一个程序来进行测试 .在这里我使用的是针对Google浏览 ...

  8. 黑马程序员_java基础笔记(12)...内省(IntroSpector)

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— 1,了解JavaBean.2,BeanUtils工具包. 1,了解JavaBean. ...

  9. GPS数据包格式及数据包解析

    GPS数据包解析 GPS数据包解析 目的 GPS数据类型及格式 数据格式 数据解释 解析代码 结构体定义 GPRMC解析函数 GPGGA解析函数 测试样例输出 gps数据包格式 gps数据解析 车联网 ...

  10. 文件系统层级结构标准(FHS)

    参考资料:FHS 简介 FHS目前发展到3.0版本,发布于2015年6月3日,由Linux基金会在负责维护.它规定了Linux的文件层级结构,使得各Linux发行版.软件开发商知道应该将哪些文件放在哪 ...