目录

前言

1. freetype和相关概念简介

2.freetype显示文字流程和主要函数

2.1 包含头文件及API头文件:ft2build.h

2.2 初始化: FT_InitFreetype

2.3 加载(打开)字体Face: FT_New_Face

2.4 设置字体大小:FT_Set_Char_Size或FT_Set_Pixel_Size

2.4.5 (可选)选择charmap: FT_Select_Charmap

2.5 得到位图FT_Load_Char

2.6 显示单个文字


前言

学过单片机的朋友都会用点阵来显示一个字符,无非就是把点阵里的值取出来一个个在屏幕上显示,修改字符大小需重新定义点阵,或者经过运算,freetype是一个矢量字体引擎,可以显示ttf字体文件中的字符。点阵和矢量字体并无优劣,点阵在资源少,显示字符少的情况下更加适合,矢量字体在资源多,显示字符多,显示要求变化大的情况下更加好。

移植freetype详见Linux安装zlib、libpng、freetype给交叉编译工具链使用

1. freetype和相关概念简介

freetype

一个免费的、可移植的字体引擎开源库,提供统一的接口来访问多种字体格式文字。
官网:The FreeType Project

矢量字体(Vector font)

矢量字体又叫Outline font,即轮廓字体。

矢量字体显示有3步:
1)确定关键点;2)使用数学曲线(贝塞尔曲线)连接关键点;3)填充闭合曲线内部空间。

字体的关键点

以字母“A”为例,它的关键点如下图黄色点所示:

然后用数学曲线(如贝塞尔曲线),将这些关键点连接起来:

填充封闭闭合区间,就显示出字母“A”。如下图所示:

字符编码

在计算机里一切都是用数字来表示,字符编码本质上就是解决一个字符用什么数字来表示的问题。比如字符 A,用 0x41 来表示它。我们常见的ASCII码有128个字符,用一个字节,8位表示。

ANSI编码

ANSI不是一种特定的编码

ANSI 是 ASCII 的扩展,向下包含 ASCII。对于 ASCII 字符仍以一个字节来表示,对于非 ASCII 字符则使用 两个字节来表示。并没有固定的 ASNI 编码,它跟“本地化”(locale)密切相关。比如在中国大陆地区, ANSI 的默认编码是 GB2312;在港澳台地区默认编码是 BIG5。以数值“ 0xd0d6”为例,对于 GB2312 编码它表示“中”;对于 BIG5 编码它表示“ 笢”。所以对于 ANSI 编码的 TXT 文件,如果你打开它发现乱码,那么还得再次细分它的具体编码。

UNICODE字符集

在 ANSI 标准中,很多种文字都有自己的编码标准,汉字简体字有 GB2312、繁体字有 BIG5,这难免同一个数值对应不同字符。比如数值“ 0xd0d6”,对于GB2312 编码它表示“中”;对于 BIG5 编码它表示“ 笢”。这造成了使用 ANSI 编码保存的文件,不适合跨地区交流。

UNICODE 字符集(也可以叫编码,实际上叫字符集更加合适)就是解决这类问题:对于地球上任意一个字符,都给它一个唯一的数值。

UNICODE 仍然向下兼容 ASCII,但是对于其他字符会有对应的数值,比如对于“中”、“ 笢”,它们的数值分别是: 0x4e2d、 0x7b22UNICODE 中的数值范围是 0x0000 至 0x10FFFF。

UTF-8编码

Unicode 统一了所有字符的编码,是一个 Character Set,也就是字符集,字符集只是给所有的字符一个唯一编号,但是却没有规定如何存储,一个编号为 65 的字符,只需要一个字节就可以存下,但是编号 40657 的字符需要两个字节的空间才可以装下,而更靠后的字符可能会需要三个甚至四个字节的空间。

这时,用什么规则存储 Unicode 字符就成了关键,我们可以规定,一个字符使用四个字节存储,也就是 32 位,这样就能涵盖现有 Unicode 包含的所有字符,这种编码方式叫做 UTF-32(UTF 是 UCS Transformation Format 的缩写)。UTF-32 的规则虽然简单,但是缺陷也很明显,假设使用 UTF-32 和 ASCII 分别对一个只有西文字母的文档编码,前者需要花费的空间是后者的四倍(ASCII 每个字符只需要一个字节存储)。

在存储和网络传输中,通常使用更为节省空间的变长编码方式 UTF-8,UTF-8 代表 8 位一组表示 Unicode 字符的格式,使用 1 - 4 个字节来表示字符。

wchar_t

char型的常见编码方式是ASCII,ASCII编码是一种基于8位二进制数的字符编码算法,能表示256种可能的字符。

wchar_t的出现,是出于程序兼容多语言的需求,因为在很多语言中,字符的数量远远大于256。因此wchar_t出现了,wchar_t全称是wide character type,也就是宽字符。

wchar_t *a=“哈”

哈字的UNICODE值就被保存在a指向的地址了。

我们编写 C 程序时,输入的字符本身(如上面的哈字)可以使用 ANSI 编码,或是 UTF-8 编码;在编译程序时,可以使用以下的选项告诉编译器:

-finput-charset=GB2312
-finput-charset=UTF-8

如果不指定“ -finput-charset”, GCC 就会默认 C 程序的编码方式为 UTF-8,即使你是以 ANSI 格式保存,也会被当作 UTF-8 来对待。对于编译出来的可执行程序,可以指定它里面的字符是以什么方式编码,可以使用以下的选项编译器:

-fexec-charset=GB2312
-fexec-charset=UTF-8

2.freetype显示文字流程和主要函数

2.1 包含头文件及API头文件:ft2build.h

#include <ft2build.h>
#include FT_FREETYPE_H // 基础的FreeType 2 API
#include FT_GLYPH_H // 管理Glyph Images

2.2 初始化: FT_InitFreetype

初始化FreeType库

FT_Library    library;
error = FT_Init_FreeType( &library );              /* initialize library */

2.3 加载(打开)字体Face: FT_New_Face

face描述了一个给定(印刷)字体和样式

FT_Face       face;
error = FT_New_Face( library, 字体文件路径, 0, &face ); /* create face object */

2.4 设置字体大小:FT_Set_Char_Size或FT_Set_Pixel_Size

FT_Set_Char_Size:设置字符尺寸(nominal size in points,1pt=0.376mm);

这个函数是设置物理上的大小,freetype会根据设备分辨率调整像素,一般不怎么用这个

FT_Set_Pixel_Size:设置字符尺寸(nominal size (in pixels),单位是像素点);

这个函数是设置像素大小,一半用这个比较多。

2.4.5 (可选)选择charmap: FT_Select_Charmap

一个字体可能可以支持不同的编码,支持哪些编码的信息会被放在字体文件的charmaps中。face对象创建时,默认从字体文件中查找Unicode charmap,也就是如果使用Unicode就不需要指定charmap了。如果想要改变,可以调用该函数。

当前charmap可以通过face->charmap来访问。

我们这里不需要设置。

2.5 得到位图FT_Load_Char

FT_Load_Char(face, charcode, FT_LOAD_RENDER),可以直接得到glyph对应的bitmap。

wchar_t *chinese_str = L"哈";
error = FT_Load_Char( face, chinese_str[0], FT_LOAD_RENDER );

可以看到,传入的是2.3中定义的FT_Face  face;。生成一个字符的点阵位图时,位图保存在哪里?

FT_Face结构体内部有一个结构体成员, FT_GlyphSlot      glyph

FT_GlyphSlot结构体内部有一个成员,FT_Bitmap         bitmap;

生成第2个字符位图时,也会保存在这,会覆盖第1个字符的位图

我们往往自己定义一个FT_GlyphSlot结构体slot,在加载字体后就将face->glyph传给他。

FT_GlyphSlot  slot;slot = face->glyph;

这些结构体都是指针,所以其实就是赋值了地址face->glyph->bitmap发生了变化,slot->bitmap也会变化。

FT_Bitmap 结构体:

  typedef struct  FT_Bitmap_{int             rows;int             width;int             pitch;unsigned char*  buffer;short           num_grays;char            pixel_mode;char            palette_mode;void*           palette;} FT_Bitmap

重要的成员是rows、width,buffer,含义如下图,其他成员作用可以自己搜一下。

由于位图中每一个像素用一个字节来表示,为8位灰度图。

参考:

嵌入式Linux入门-Framebuffer应用编程在Linux系统下画个点

到这应该就知道怎么在屏幕上显示了吧。

2.6 显示单个文字

draw_bitmap( FT_Bitmap*  bitmap,FT_Int      x,FT_Int      y)
{FT_Int  i, j, p, q;FT_Int  x_max = x + bitmap->width;FT_Int  y_max = y + bitmap->rows;//printf("x = %d, y = %d\n", x, y);for ( j = y, q = 0; j < y_max; j++, q++ ){for ( i = x, p = 0; i < x_max; i++, p++ ){if ( i < 0      || j < 0       ||i >= var.xres || j >= var.yres )continue;//image[j][i] |= bitmap->buffer[q * bitmap->width + p];lcd_put_pixel(i, j, bitmap->buffer[q * bitmap->width + p]);}}
}

参数里的x,y是在显示的位置的坐标。

下面函数为在lcd上画一个点的函数。

lcd_put_pixel(int x, int y, unsigned int color)

显示一行文字你可以用位图,一个个显示字,但是并不完美,更好的方式可以参考【硬核】韦东山:使用freetype显示一行文字 - 知乎

嵌入式应用-详解移植并使用freetype显示文字相关推荐

  1. FileReader详解与实例---读取并显示图像文件 | JS Mix

    2019独角兽企业重金招聘Python工程师标准>>> FileReader详解与实例---读取并显示图像文件 | JS Mix. 转载于:https://my.oschina.ne ...

  2. c语言贪吃蛇详解5.GameOver功能与显示成绩

    c语言贪吃蛇详解5.GameOver功能与显示成绩 以前我们已经做出来了一个能吃东西变长的蛇.不过它好像不会死... 现在就来实现一下game over的功能吧. 写个函数判断蛇是否撞到自己或者撞到墙 ...

  3. 微信 html 字体 自动换行,详解微信小程序-canvas绘制文字实现自动换行

    在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvascontext.filltext参数为 我们只能设置文本的最大宽度,这就产生一定的了问题.如果我们绘制的文本长度不确定或者 ...

  4. Linux netstat命令详解和使用例子(显示各种网络相关信息)

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  5. 转:FileReader详解与实例---读取并显示图像文件

    ~~~针对需要读取本地图像,并立即显示在浏览器的情况,由于chrome firefox出于安全限制,input file并不返回文件的真实路径,经测试IE6/7/8都会返回真实路径,所以chrome, ...

  6. SpringBoot实现文件上传下载功能详解(附带中文名称显示乱码问题的解决)

    文件上传模块: 首先,需要设置一个存放上传文件的目录,可以在接口中指定,也可以在配置文件中提前设置好. 这边采用的是配置文件的形式,在application.properties中指定路径为stati ...

  7. ImageDraw类详解:几何图形的绘制与文字的绘制

    python PIL图像处理模块中的ImageDraw类支持各种几何图形的绘制和文本的绘制,如直线.椭圆.弧.弦.多边形以及文字等. 下面直接通过示例来进行说明: #-*- coding: UTF-8 ...

  8. html质感阴影_详解CSS3的图层阴影和文字阴影效果使用

    box-shadow图层阴影 box-shadow:阴影类型 X水平偏移(可取正负值) Y垂直偏移(可取正负值) 阴影大小 阴影扩展 阴影颜色值 阴影类型可以省略,默认为外投影,当它的值为inset时 ...

  9. df 和 du 命令详解

    df命令详细用法 a:显示全部的档案系统和各分割区的磁盘使用情形 i:显示i -nodes的使用量 k:大小用k来表示 (默认值) t:显示某一个档案系统的所有分割区磁盘使用量 x:显示不是某一个档案 ...

最新文章

  1. 烧写文件系统——韦东山嵌入式Linux学习笔记11
  2. 維護webflow:request、session、application、page
  3. 【Docker】安装与常用命令
  4. python中ipo模型有_python ipo模型是指什么?_后端开发
  5. 郎溪 溪流_到无限(溪流)和超越!
  6. [html] a标签可以再嵌套a标签吗?为什么?如果不行,那又想要嵌套效果怎么解决呢?
  7. 域控下发脚本_域环境下做到单用户登陆控制脚本
  8. bat执行exe程序_dos命令start教程,并行运行exe程序或者启动bat批处理cmd脚本
  9. 年度大战即将拉开!iPhone 11系列后,轮到华为Mate30系列表演了
  10. 计算机专业动漫设计毕业论文,计算机动漫设计与制作专业毕业论文26850.doc
  11. element ui 分页增删改查_【新插件发布】AzureAD运维Excel版插件,增删改查快10倍c以上!...
  12. 修改 jtable 显示格式
  13. LintCode Python 简单级题目 41.最大子数组 - 44.最小子数组和
  14. Java工程师如何在Docker上进行开发
  15. Boost Asio Examples(整理)
  16. c语言读取三菱plc数据,c#通过网线读取三菱PLC数据
  17. 无线传输课程设计,基于ZigBee的水质监测系统设计
  18. [lampp] 不能通过互联网连接数据库 MySQL is not accessable via network
  19. vue实现表格列位置的拖拽
  20. 利用simulink分析系统各种传递函数的BODE图、阶跃响应、单位脉冲响应

热门文章

  1. 老板要如何去激励自己的员工?
  2. 工具“正确”打开方式——如何用notion来谈恋爱
  3. 并行与并发的区别,一瞬间就能理解并记住
  4. 软考高级-信息系统管理师之综合测试与管理(最新版)
  5. Linux-新用户创建和删除
  6. (转)快商通与商务通将客人网页内文本框输入的内容传到客服端对话界面显示...
  7. 互动作业组的计算机在哪,互动作业和作业互动组区别介绍 看起来有很相似
  8. Windows10电脑用户中文名修改为英文名的详细教程【亲测有用】
  9. 剧场版复活的f 剧情
  10. 营销活动思维导图系列(共55份)