数码相框——2、3、1 freetype库实现任意大小的字体 理论介绍

本文深入探讨了Freetype矢量字体库的工作原理,包括矢量字体的描述方式、文字显示流程及Freetype库的使用方法。详细介绍了如何通过Freetype加载字体文件、设置字体大小、加载和渲染字形数据,为开发者提供了全面的矢量字体处理指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from:https://www.cnblogs.com/lifexy/p/8503070.html
freetype中文文档:https://wenku.baidu.com/view/2d24be10cc7931b765ce155b.html
freetype教程中文:https://wenku.baidu.com/view/e7149f6748d7c1c708a14574.html

COTENT

1、矢量字体文件原理

2、一个文字的显示过程

3、如何使用freetype

·· 1)包含头文件
·· 2)初始化库
·· 3)加载face对象
·· 4)设置字体大小
·· 5)根据字符的索引值加载glyphy

1、矢量字体原理

矢量字体原理:
① 将字体描述成若干条闭合曲线,提取关键点
② 贝塞尔曲线连接关键点
③ 填充封闭空间
font16X8和hzk得到的点阵是固定的,而矢量字体可以设置大小
什么是矢量字体库?
每种矢量字库(.ttf .ttc)都是由两部分组成,一部分是汉字的索引信息(charmaps),一部分是汉字的字形(glyph)数据。
freetype库的作用?
从矢量字体库中把关键点取出,使用freetype库,生成位图点阵。

2、矢量文字的显示过程

① 给定一个文字,可以确定它的编码值
② 根据编码值(freetype支持多种编码),从字体文件中找汉字的字形数据(glyphy)
③ 设置字体大小
④ 用某些函数把glyphy里的关键点,缩放为设置的大小
⑤ 把glyphy转换为位图
⑥ 在LCD上显示出来

3、如何使用freetype

1)包含头文件

#include <ft2build.h>
#include FT_FREETYPE_H

2)初始化库

使用FT_Init_FreeType()函数初始化一个FT_Library类型的变量

 #include <ft2build.h>
 #include FT_FREETYPE_H

  FT_Library  library;  //库的句柄
  ...
  error = FT_Init_FreeType( &library );
  if ( error )
  {
    ... an error occurred during library initialization ...
  }

3)加载face对象

a. 从字体文件中加载
通过FT_NEW_Face()打开一个字体文件,然后提取该文件的一个FT_Face类型的face变量

  FT_Library  library;   /* 库的句柄    */
  FT_Face     face;      /* face对象的句柄  */
  
  error = FT_Init_FreeType( &library );
  if ( error ) { ... }
  
  error = FT_New_Face( library,
                       "/usr/share/fonts/truetype/arial.ttf",  //字形文件
                       0,
                       &face );

b.从内存中加载

 error = FT_New_Memory_Face( library,
                              buffer,    /* first byte in memory */
                              size,      /* size in bytes        */
                              0,         /* face_index           */
                              &face );

c.其他来源

4)设置字体大小

  error = FT_Set_Char_Size(
            face,    /* handle to face object           */
            0,       /* char_width in 1/64th of points  */
            16*64,   /* char_height in 1/64th of points */
            300,     /* horizontal device resolution    */
            300 );   /* vertical device resolution      */
  error = FT_Set_Pixel_Sizes(
            face,   /* handle to face object */
            0,      /* pixel_width           */
            16 );   /* pixel_height          */

5)根据字符的索引值加载glyphy

a. 选择charmap(支持多种编码方式)
使用其它字符编码,则通过FT_Select_Charmap()来获取

error = FT_Select_Charmap(
face,                /* 目标face对象 */
FT_ENCODING_BIG5 ); /* big5编码 */

//FT_ENCODING_BIG5枚举定义在FT_FREETYPE_H中
//FT_ENCODING_GB2312 :GB2312编码
//该函数头文件位于:FT_FREETYPE_H (freetype/freetype.h).

b. 获取编码的索引(找到)

通过FT_Get_Char_Index()函数将字符编码转换为一个字形数据(glyph)索引 (Freetype默认是utf-16编码类型)。若glyph_index为NULL,表示没找到字形(glyph)索引。

glyph_index = FT_Get_Char_Index( face, charcode );   

c. 通过索引,从face中加载字形(取出)

获得字形索引后,接下来便根据字形索引,来将字形图像存储到字形槽(FT_GlyphSlot slot;)中.

字形槽: 每次只能存储一个字形图像。 slot = face->glyph;

error = FT_Load_Glyph(

face, /* face对象的句柄 */

glyph_index, /* 字形索引 */

load_flags ); /* 装载标志,一般填FT_LOAD_DEFAULT*/

d.转为位图

通过FT_Render_Glyph()函数,将字形槽的字形图像转为位图,并存到 face->glyph->bitmap->buffer[]里

error = FT_Render_Glyph( face->glyph, /* 字形槽 */

render_mode ); /* 渲染模式 */

render_mode标志可以设为以下几种:

FT_RENDER_MODE_NORMAL:表示生成位图每个像素是RGB888的
FT_RENDER_MODE_MONO :表示生成位图每个像素是1位的(黑白图)

并更新face->glyph->bitmap下的其它成员,比如:

int             rows;         //该位图总高度,有多少行
int             width;        //该位图总宽度,有多少列像素点
int             pitch:        //指一行的数据跨度(所占字节数),比如对于24位(3字节)的24*30汉字,则pitch=24*3

char            pixel_mode    //像素模式,1 指单色的,8 表示反走样灰度值

unsigned char*  buffer        //glyph 的点阵位图内存绶冲区

在这里插入图片描述
以水平方向为例:在笛卡尔坐标系下如图所示
FT_GlyphSlot slot = face->glyph;
bitmap结构体的成员与图中对应关系:
slot->bitmap_left = bearingX; //距离左边的空余像素
slot->bitmap_top = bearingY; //
slot->advance.x = advance; //在竖直方向上:slot->advance.y = advance;
slot->advance.y = 0; //在竖直方向上:slot->advance.x = 0;

slot->bitmap.width = width;
slot->bitmap.rows = height;

e. 变换——移动、旋转

FT_Vector delta;
delta.x = 0;
delta.y = 0;
error = FT_Set_Transform(

face, /* 目标face对象 */

&matrix, /* 指向2x2矩阵的指针,写0表示不旋转,使用正矩形 */

&delta ); /*字体坐标位置(用的笛卡尔坐标),以1/64像素为单位表示,写0表示原点是(0,0) */

matrix = 0则不旋转

f. 用FT_Load_Char()来代替FT_Get_Char_Index()、FT_Get_Load_Glyph()和FT_Render_Glyph()

error = FT_Load_Char( face, charcode, FT_LOAD_RENDER );

其中FT_LOAD_RENDER:表示直接将图像转为位图,所以不需要使用FT_Render_Glyph()函数

该函数默认生成的位图是默认生成的FT_RENDER_MODE_NORMAL类型,RGB888的。

若想生成FT_RENDER_MODE_MONO(黑白图)类型,操作如下:

error = FT_Load_Char( face, charcode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME );

生成出来的位图像素,每一个像素1bit,每8个像素点便表示 face->glyph->bitmap->buffer[]里的一个字节。

这份文档提供了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、付费专栏及课程。

余额充值