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