LVGL学习之路——基于lv_lib_freetype库的TTF字体文件动态加载中文字体(阿里普惠字体)

前言

  在学习lvgl中,在英文字体上很多人都用过,但是中文字体往往需要靠取模去实现。那么我就在想,如何像windows那样加载动态的字体呢,这样想做多大字体都行。于是就开始了字体的移植。

什么是ttf字体:

  字库是输出设备的一个组成部分。由于汉字不同于西方字体,字符集非常庞大,不能用单字节表示,因此postscript level i的rip不能使用汉字,很多西文软件也不支持汉字。
桌面出版系统使用的字库有两种标准: postscript字库和truetype字库。这两种字体标准都是采用曲线方式描述字体轮廓,因此都可以输出很高质量的字形。
常用的字库标准是truetype字库,truetype字体是windows操作系统使用的唯一字体标准,macintosh计算机也用 truetype字体作为系统字体。truetype字体的最大优点是可以很方便地把字体轮廓转换成曲线,可以对曲线进行填充,制成各种颜色和效果,它可以进一步变形,制作特殊效果字体,因此经常用来制作一些标题字或花样字。 truetype字便宜,字款丰富。但一般情况厂truetype字不能直接由rip输出。需要经过特殊处理,比如转成曲线或输出时下载,使用起来较麻烦。速度也要慢一些,尤其是处理大量文字时很不方便,因此不适合用来作为页面的正文文字使用。
  truetype字体也用来作为postscript字库的显示字用,各字库公司同时都有这两种标准的产品。因此当使用truetype字体制作版面时,输出时仍然可以将它代换成postscript字库输出
在一些特殊的场合,系统字符集不包含你要用的字体,这时候必须使用自己的字体文件,如甲骨文等古文字处理,一般在系统盘\WINDOWS\Fonts里,直接双击能查看是什么样的字体。

ttf字体解析器

 我们一般用开源的freetype去解析.ttf字体文件,然后在lvgl官方给的库lv_lib_freetype封装成lvgl的api去使用。经过我苦找关于二者的联动任然只有官方的README可用,而它的README也就寥寥数语。于是我就开始了自己摸索的过程。

移植过程

 首先最重要的就是确定我们的硬件,找到对应的交叉编译工具,比如我这里是arm-linux-gnueabihf-gcc然后点击下载freetype源码https://download.savannah.gnu.org/releases/freetype/freetype-2.10.0.tar.gz

wget https://download.savannah.gnu.org/releases/freetype/freetype-2.10.0.tar.gz # 下载
tar zxvf freetype-2.10.0.tar.gz	# 解压freetype
cd freetype-2.10.0/				# 进入freetype文件夹内
./configure CC=arm-linux-gnueabihf-gcc --host=arm-linux --prefix=$PWD/INSTALL --with-zlib=no --with-png=no 			# 主要是CC这里填交叉编译工具
make
make install

最后会生成一个INSTALL文件夹,使用tree看一下INSTALL文件结构

.
├── include
│   └── freetype2
│       ├── freetype
│       │   ├── config
│       │   │   ├── ftconfig.h
│       │   │   ├── ftheader.h
│       │   │   ├── ftmodule.h
│       │   │   ├── ftoption.h
│       │   │   └── ftstdlib.h
│       │   ├── freetype.h
│       │   ├── ftadvanc.h
│       │   ├── ftbbox.h
│       │   ├── ftbdf.h
│       │   ├── ftbitmap.h
│       │   ├── ftbzip2.h
│       │   ├── ftcache.h
│       │   ├── ftchapters.h
│       │   ├── ftcid.h
│       │   ├── ftcolor.h
│       │   ├── ftdriver.h
│       │   ├── fterrdef.h
│       │   ├── fterrors.h
│       │   ├── ftfntfmt.h
│       │   ├── ftgasp.h
│       │   ├── ftglyph.h
│       │   ├── ftgxval.h
│       │   ├── ftgzip.h
│       │   ├── ftimage.h
│       │   ├── ftincrem.h
│       │   ├── ftlcdfil.h
│       │   ├── ftlist.h
│       │   ├── ftlzw.h
│       │   ├── ftmac.h
│       │   ├── ftmm.h
│       │   ├── ftmodapi.h
│       │   ├── ftmoderr.h
│       │   ├── ftotval.h
│       │   ├── ftoutln.h
│       │   ├── ftparams.h
│       │   ├── ftpfr.h
│       │   ├── ftrender.h
│       │   ├── ftsizes.h
│       │   ├── ftsnames.h
│       │   ├── ftstroke.h
│       │   ├── ftsynth.h
│       │   ├── ftsystem.h
│       │   ├── fttrigon.h
│       │   ├── fttypes.h
│       │   ├── ftwinfnt.h
│       │   ├── t1tables.h
│       │   ├── ttnameid.h
│       │   ├── tttables.h
│       │   └── tttags.h
│       └── ft2build.h
├── lib
│   ├── libfreetype.a
│   ├── libfreetype.la
│   ├── libfreetype.so -> libfreetype.so.6.17.0
│   ├── libfreetype.so.6 -> libfreetype.so.6.17.0
│   ├── libfreetype.so.6.17.0
│   └── pkgconfig
│       └── freetype2.pc
└── share
    └── aclocal
        └── freetype2.m4

8 directories, 57 files

下载我们的lv_lib_freetype的库,并把freetype库中的freetype2文件夹和它合并

lv_lib_freetype/
├── freetype
│   ├── config
│   │   ├── ftconfig.h
│   │   ├── ftheader.h
│   │   ├── ftmodule.h
│   │   ├── ftoption.h
│   │   └── ftstdlib.h
│   ├── freetype.h
│   ├── ftadvanc.h
│   ├── ftbbox.h
│   ├── ftbdf.h
│   ├── ftbitmap.h
│   ├── ftbzip2.h
│   ├── ftcache.h
│   ├── ftchapters.h
│   ├── ftcid.h
│   ├── fterrdef.h
│   ├── fterrors.h
│   ├── ftgasp.h
│   ├── ftglyph.h
│   ├── ftgxval.h
│   ├── ftgzip.h
│   ├── ftimage.h
│   ├── ftincrem.h
│   ├── ftlcdfil.h
│   ├── ftlist.h
│   ├── ftlzw.h
│   ├── ftmac.h
│   ├── ftmm.h
│   ├── ftmodapi.h
│   ├── ftmoderr.h
│   ├── ftotval.h
│   ├── ftoutln.h
│   ├── ftpfr.h
│   ├── ftrender.h
│   ├── ftsizes.h
│   ├── ftsnames.h
│   ├── ftstroke.h
│   ├── ftsynth.h
│   ├── ftsystem.h
│   ├── fttrigon.h
│   ├── fttypes.h
│   ├── ftwinfnt.h
│   ├── ftxf86.h
│   ├── t1tables.h
│   ├── ttnameid.h
│   ├── tttables.h
│   ├── tttags.h
│   └── ttunpat.h
├── ft2build.h
├── lv_freetype.c
├── lv_freetype.h
└── lv_freetype.mk

这里的lv_freetype.mk是我自己加的,里面将.h的路径放入到自己inculde path中,将.c放入编译行列中。这部分不同的硬件编译makefile有所不同,总而言之就是把文件夹加入自己的工程里。然后别忘了添加动态库

lib
└── libfreetype.so

0 directories, 1 file

在makefile里也要用 -L./lib -lfreetype将动态库编译进去,此时我们的就可以写例子了
根据官方github的示例,我们修改一下

lv_freetype_init(64); /*Cache max 64 glyphs*/

/*Create a font*/
static lv_font_t font1;
lv_freetype_font_init(&font1, "./Alibaba-PuHuiTi-Regular.ttf", 32);

/*Create style with the new font*/
static lv_style_t style;
lv_style_init(&style);
lv_style_set_text_font(&style, LV_STATE_DEFAULT, &font1);

/*Create a label with the new style*/
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
lv_obj_add_style(label, LV_LABEL_PART_MAIN, &style);
lv_label_set_text(label, "你好,世界!");

这个字体是阿里普惠字体可以从https://alibabafont.taobao.com/wow/alibabafont/act/alifont下载,我们make一下发现,会出现如下错误

/home/kirto/8ms-sstar/lv_lib_freetype/lv_freetype.c: In function ‘get_glyph_dsc_cache_cb’:
/home/kirto/8ms-sstar/lv_lib_freetype/lv_freetype.c:69:72: error: ‘lv_font_t’ {aka ‘const struct _lv_font_struct’} has no member named ‘user_data’
  lv_font_fmt_freetype_dsc_t * dsc = (lv_font_fmt_freetype_dsc_t *)(font->user_data);
                                                                        ^~
/home/kirto/8ms-sstar/lv_lib_freetype/lv_freetype.c: In function ‘lv_freetype_font_init’:
/home/kirto/8ms-sstar/lv_lib_freetype/lv_freetype.c:249:9: error: ‘lv_font_t’ {aka ‘struct _lv_font_struct’} has no member named ‘user_data’
     font->user_data = dsc;
         ^~
Makefile:29: recipe for target 'lv_freetype.o' failed
make: *** [lv_freetype.o] Error 1

这里是说lv_font_t这个结构体没有user_data这个属性,这里是被宏定义注释了,我们需要从lv_config里找到这个宏定义,打开这个属性

/*1: Add a `user_data` to drivers and objects*/
#define LV_USE_USER_DATA        1

再make就完成了,运行的时候需要加入字体文件和依赖库libfreetype.so.6(我也奇怪为什么是.6文件),然后运行就可以看到结果了

你可能感兴趣的:(lvgl,linux,gui,ttf,嵌入式,交叉编译)