也称位图字体,其中每个字形都以一组二维像素信息表示。
难以进行放缩,特定的点阵字体只能清晰地显示在相应的字号下。否则文字呗强行放大会有损字形,产生马赛克式的锯齿边缘。
对于字号8-14px的尺寸较小的汉字字体,现今仍然被使用于荧幕显示上,能够提供更高的显示效果。
bdf,pcf,fnt,hbf
Adobe 公司推出的一种可阅读性非常强的文本格式点阵字库文件,英文全称:Bitmap Distribution Format 。
将汉字的笔划边缘用直线段描述成封闭的曲线,并将线段各端点的坐标经压缩存储。
每个汉字的笔画不一样,所以每个汉字数据长度也不同,只能采用索引的方式。每种矢量字库都由两部分组成:汉字索引信息,汉字字形数据。
显示文字时,便提取出各端点,并通过贝塞尔曲线来连接各个坐标,最后填充封闭空间。
1985年由Adobe公司提供的一套矢量字体标准,该标准基于PostScript Description Language(PDL)(高端打印机首选描述语言)。
非开放字体,Adobe对使用Type1的公司收高额费用。
使用三次贝塞尔曲线(PostScript 曲线)来描述字形,更加精确美观,用于打印更好;
https://zh.wikipedia.org/wiki/TrueType
1991年由Apple公司与Microsoft公司联合提出另一套矢量字标准。
使用二次贝塞尔曲线(TrueType 曲线)来描述字形,在数学上更加简单,处理上更加快速,但是需要更多的点去描述。
文件后缀.ttf
https://zh.wikipedia.org/wiki/OpenType
1995年,Adobe公司和Microsoft公司开始联手开发一种兼容Type1和TrueType,并且真正支持Unicode的字体。
文件后缀.otf
注:
TTF 扩展名的 O 图标的表示 OpenType - TrueType 字体.ttf
, 采用的是 TrueType 曲线, 支持 OpenType 的高级特性。
TTF 扩展名的 T 图标的表示 TrueType 字体.ttf,
采用的是 TrueType 曲线, 不支持 OpenType 特性。
OTF 扩展名的 O 图标的表示 OpenType - PostScript 字体.otf
, 采用的是 PostScript 曲线, 支持 OpenType 高级特性。
https://www.likecs.com/show-795823.html
https://www.likecs.com/show-306335952.html
矢量字在不同字号下,根据点阵尺寸,显示的精细程度也不一样。
在不同的字号下,根据最简单的缩放原理,将所有的点缩放到合适的位置,再确定曲线。这时候,一条边就占据不了整列像素,或者一条边压在了两列像素的中间,这样就造成了灰色的线条。而这并不是我们想要的效果,Photoshop通过USM锐化滤镜,将虚边得以逐步清晰,以达到所要的矢量字。
苹果系统通过调整整体点阵的位置,将所有的点适当便宜半个像素以内的位置,可以实现较为清晰的字体。如果在关闭了消除锯齿方式,则有些边线由于占据不了半个像素,而不能够显示,这就形成了所谓的缺边或者缺笔划。
有些软件,比如Adobe Acrobat,通过一种较为复杂的方式,以实现矢量字的清晰。将某些关联的点作为一个segment,并且局部偏移到邻近的整数位,而其他部分不动。这种方法目前较为流行,可以实现比苹果和ps还要清晰的矢量效果。
微软的TTF为了保证小字号下的清晰,可谓是用尽了方法。首先,在庞大的字库,内置了数个字号的点阵字,接着才是矢量字。比如宋体,内置了12、14、16、18等几个点阵字库,在这些之外才使用矢量字库来渲染。这也是为什么一个TTF文件要几兆甚至几十兆的容量,不过内嵌的点阵字越多,在不同字号下实现的效果自然越好。别小看了这些点阵字,每一个都是平面设计师在工具上画的,并非由软件生成。唉,可怜的设计师啊~~~~~~
不过,有个特例。比如Arial字体,内部全是矢量字,但各种尺寸下都是这么清晰。为什么呢?
原来,微软在字库中加入了解释程序,interpreter,一种专门用于字库渲染的脚本命令。在不同的字号下,都有相应的语句,将矢量字得以最清晰化。这是一种复杂的技术,微软也觉得不能广泛使用,所以只有在部分的英文字库中才有,而且该脚本对应每个字都有一段代码,容量非常大,用在汉字上几乎是不可能,除非是整个文字不多于100个才能使用。
在1998年的时候,微软声称发明了一种新的技术,能在LCD上将矢量字体的清晰度提高到300%。而后,出现了名为Microsoft Reader的软件,我还用过几个版本。Adobe也不甘示弱,随即在Acrobat 4中对CoolType进行了支持,而Linux的FreeType库也开始支持次像素平滑。据我多年的研究观察,Acrobat做的***,最灵活,而微软的缺少适当的调节工具,Linux的次像素平滑简直就是垃圾,照虎画猫。
可使用freetype库实现矢量字体显示
一个开源的字体引擎,支持多种字符集编码(utf-8等)
支持多种字体文件格式,提供统一的访问接口;包括TureType,OpenType,Type1, CID,CFF,Windows FON/FNT,X11,PCF等。
采用面向对象设计,可灵活根据需要进行剪裁
FreeType移植到 STM32 单片机以支持矢量字体
数码相框-通过freetype库实现矢量显示
FreeType2使用总结
UTF-8
Unicode
Fonts
很详细啦
Online Font Converter
安装好后在lvgl/scripts/built_in_font/
路径下
python3 built_in_font_gen.py --size 24 --font ~/Downloads/user-font/user-font.otf --bpp 4 -o ./user_font_24.c -r 0x20-0x7F
是一些写好的脚本,输入可以改的参数,默认 --format bin
直接使lv_font_conv
可以
使用lv_font_conv离线工具
LVGL添加自定义图标字体
LVGL学习使用lv_font_conv离线工具 Font字体 FontAwesome图标字体的使用
工具:阿里矢量图标库
glyph_bitmap
按顺序存储字形的点阵数据
不同字符存储的点阵字节数不同,为了节省空间,将字符中空的行列部分不转化存储。通过其他的描述信息来控制字符的显示位置。
/*Store the image of the glyphs*/
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
/* U+E644 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
0xff, 0x40, 0x2, 0x10, 0x0, 0x0, 0x0, 0x4,
0xff, 0x40, 0x1, 0xed, 0x10, 0x0, 0x0, 0x4,
0xff, 0x40, 0x0, 0x9, 0xfd, 0x10, 0x0, 0x4,
0xff, 0x40, 0x0, 0x0, 0x9, 0xfd, 0x10, 0x4,
0xff, 0x40, 0x0, 0x0, 0x0, 0x9, 0xfd, 0x14,
0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x9, 0xfe,
0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9,
0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x8, 0x40, 0x0, 0x0, 0x0, 0x0,
/* U+E646 "" */
0x1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x10, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xf6, 0x4, 0x44, 0x44, 0x44, 0x44, 0x44,
0x44, 0x44, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x7, 0xf6, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x2, 0xcf, 0xf6, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x5f, 0xd3, 0xf6, 0x1e,
0xee, 0xee, 0xee, 0xea, 0x5, 0xfc, 0x0, 0xf6,
0x3, 0x33, 0x33, 0x33, 0x32, 0x1, 0xaf, 0x90,
0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6,
0xfd, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x2c, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x6, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x62,
/* U+E648 "" */
0x0, 0x0, 0x0, 0x0, 0x47, 0x74, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xfe, 0xef,
0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfb,
0x20, 0x2, 0xbf, 0x40, 0x0, 0x0, 0x0, 0x0,
0xe, 0xa0, 0x0, 0x0, 0xa, 0xe0, 0x0, 0x0,
0x0, 0x0, 0x6f, 0x10, 0x0, 0x0, 0x1, 0xf6,
0x0, 0x0, 0x0, 0x29, 0xeb, 0x0, 0x0, 0x0,
0x0, 0xbe, 0x92, 0x0, 0x4, 0xfe, 0x94, 0x0,
0x0, 0x0, 0x0, 0x49, 0xef, 0x40, 0x1e, 0xb0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xe0,
0x6f, 0x10, 0x0, 0x0, 0x2, 0x30, 0x0, 0x0,
0x1, 0xf6, 0x9c, 0x0, 0x0, 0x0, 0x3e, 0xf5,
0x0, 0x0, 0x0, 0xc9, 0x8d, 0x0, 0x0, 0x3,
0xff, 0xff, 0x60, 0x0, 0x0, 0xd8, 0x4f, 0x40,
0x0, 0x2f, 0xc9, 0xe8, 0xf5, 0x0, 0x4, 0xf4,
0xb, 0xe4, 0x0, 0x7, 0x7, 0xe0, 0x61, 0x0,
0x4e, 0xb0, 0x0, 0xbf, 0x90, 0x0, 0x7, 0xe0,
0x0, 0x6, 0xfb, 0x10, 0x0, 0x2, 0x30, 0x0,
0x7, 0xe0, 0x0, 0x2, 0x30, 0x0, 0x0, 0x0,
0x0, 0x0, 0x7, 0xe0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x7, 0xe0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd0,
0x0, 0x0, 0x0, 0x0,
/* U+E649 "" */
0x0, 0x0, 0x0, 0x0, 0x47, 0x74, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0xfe, 0xef,
0xd4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfb,
0x20, 0x2, 0xbf, 0x40, 0x0, 0x0, 0x0, 0x0,
0xe, 0xa0, 0x0, 0x0, 0xa, 0xe0, 0x0, 0x0,
0x0, 0x0, 0x6f, 0x10, 0x0, 0x0, 0x1, 0xf6,
0x0, 0x0, 0x0, 0x29, 0xeb, 0x0, 0x0, 0x0,
0x0, 0xbe, 0x92, 0x0, 0x4, 0xfe, 0x94, 0x0,
0x0, 0x0, 0x0, 0x49, 0xef, 0x40, 0x1e, 0xb0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xe0,
0x6f, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x1, 0xf6, 0x9c, 0x0, 0x0, 0x0, 0x7, 0xe0,
0x0, 0x0, 0x0, 0xc9, 0x8d, 0x0, 0x0, 0x0,
0x7, 0xe0, 0x0, 0x0, 0x0, 0xd8, 0x4f, 0x40,
0x0, 0x0, 0x7, 0xe0, 0x0, 0x0, 0x3, 0xf4,
0xb, 0xe5, 0x0, 0x0, 0x7, 0xe0, 0x0, 0x0,
0x4e, 0xc0, 0x0, 0xaf, 0x90, 0x3, 0x7, 0xe0,
0x30, 0x6, 0xfb, 0x10, 0x0, 0x2, 0x30, 0x1f,
0xb7, 0xe5, 0xf5, 0x2, 0x30, 0x0, 0x0, 0x0,
0x0, 0x4, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x4f, 0xf8, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x60,
0x0, 0x0, 0x0, 0x0,
/* U+E98C "" */
0x6f, 0xff, 0xfc, 0x0, 0x0, 0xaf, 0xff, 0xfa,
0x7, 0xf6, 0x66, 0x50, 0x0, 0x4, 0x66, 0x6d,
0xa0, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xba, 0x7, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xb, 0xa0, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xba, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0,
0x0, 0x3, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
0x9e, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xde, 0x89, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0,
0x6f, 0x20, 0x6, 0xf1, 0x0, 0x6e, 0x0, 0x0,
0x8, 0xd0, 0x0, 0x2f, 0x40, 0x7, 0xe0, 0x0,
0x0, 0x6f, 0x20, 0x6, 0xf1, 0x0, 0x7e, 0x0,
0x0, 0x0, 0xde, 0x89, 0xfe, 0x0, 0x7, 0xe1,
0x11, 0x0, 0x1, 0x9e, 0xd8, 0xec, 0x0, 0x7f,
0xff, 0xfd, 0x0, 0x0, 0x0, 0x3, 0xec, 0x2,
0x55, 0x55, 0x40, 0x0, 0x0, 0x0, 0x3, 0x70,
/* U+E98D "" */
0x0, 0x0,。。
0x66, 0x66, 0x66, 0x60, 0x17, 0x13, 0x66, 0x63
};
glyph_dsc
bitmap_index
字符对应的glyph_bitmap
中点阵字体的索引adv_w
字符的宽度box_w
字模的宽度box_h
字模的高度ofs_x
字模水平方面偏移ofs_y
字模竖直方面偏移 (可以调整试试)static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
{.bitmap_index = 0, .adv_w = 352, .box_w = 17, .box_h = 12, .ofs_x = 2, .ofs_y = 3},
{.bitmap_index = 102, .adv_w = 352, .box_w = 18, .box_h = 15, .ofs_x = 2, .ofs_y = 1},
{.bitmap_index = 237, .adv_w = 352, .box_w = 20, .box_h = 18, .ofs_x = 1, .ofs_y = -1},
{.bitmap_index = 417, .adv_w = 352, .box_w = 20, .box_h = 18, .ofs_x = 1, .ofs_y = -1},
{.bitmap_index = 597, .adv_w = 352, .box_w = 17, .box_h = 16, .ofs_x = 3, .ofs_y = 0},
{.bitmap_index = 733, .adv_w = 352, .box_w = 16, .box_h = 17, .ofs_x = 3, .ofs_y = 0}
};
unicode_list_0
第一个开始的unicode值为0x0,后面的分别是unicode值减去第一个差值的十六进制表示
static const uint16_t unicode_list_0[] = {
0x0, 0x2, 0x4, 0x5, 0x348, 0x349
};
lv_font_fmt_txt_cmap_t cmaps
range_start
开始字符的unicode值range_length
结束字符和开始字符的unicode差值+1glyph_id_start
第一个字形的ID,在glyph_dsc
数组的index值unicode_list
指向签名的unicode_list数组list_length
列表里有几个字符/*Collect the unicode lists and glyph_id offsets*/
static const lv_font_fmt_txt_cmap_t cmaps[] =
{
{
.range_start = 58948, .range_length = 842, .glyph_id_start = 1,
.unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 6, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
}
};
/* use font */
LV_FONT_DECLEAR(lv_font_xx)
/* use symbol */
#define USER_ICON_1 "\xee\x99\x84" /* utf-8<->unicode 58948,0xE644 */
在线Unicode和UTF编码转换