minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁
CSDN好像有问题,文章中图片太多无法继续增加图片,所以文章分两个部分:上半部分地址:
《minigui 3.2.0:基于miniStudio应用TrueType字体的过程(1)》,下半部分用MarkdownPad2编辑,使用MarkdownPad2内置的图床,可能显示图片会有些慢。
TrueType字体的边缘锯齿
上节我们已经成功在miniStudio中加载了TrueType字体,但是如果你仔细看,发现这个字体效果有问题,有明显边缘锯齿和和残点,太丑陋啦,不可忍呐!
这个问题的形成原因在这里不展开说明了,MiniGUI的开发手册中有14.7
节《字体的渲染特效》专门讲到了程序解决这个问题的办法。
这里是说明如何在编程时通过设置逻辑字体风格(style)来指定字体的渲染特效消除锯齿的,对应到miniStudio图像界面中就是在选择字体的(style)
OK,边缘锯齿问题解决!
运行使用了TrueType的MiniGUI应用程序
经过上一节,我们已经成功在miniStudio中对控件设置了TrueType字体。于是满心欢喜的保存模板,去eclipse中运行程序看看效果。。。
然而冷冰冰的现实,又让我的心情跌到的谷底。。。
我认字不多,但你不要骗我,边缘锯齿是没有了,但楷体不长这样啊!
为什么miniStudio中明明设置成功的字体,到程序运行的时候就变卦了呢?为这个问题我又是好一顿折腾。
打开testgui项目的MiniGUI.cfg
,
我明白了原因,应用程序的MiniGUI.cfg
中[truetypefonts]
字段没有同步更新,而通过前面的关于MiniGUI 的运⾏时配置选项的说明,我们知道MiniGUI应用程序启动时首先是找自己当前文件夹下的MiniGUI.cfg
。这里没有指定TrueType字体,即使MiniGUI系统配置文件中有指定,也没有办法加载字体。
于是我手工将/usr/local/etc/MiniGUI.cfg
中[truetypefonts]
字段的内容复制到/testgui/path/MiniGui.cfg
中对应的[truetypefonts]
字段
再运行程序,成功。
你以为这就完了么?NO,如果你再打开miniStudio,编辑模板文件保存后,你会发现/testgui/path/MiniGui.cfg
的内容又恢复了原样!
也就是说miniStudio每次保存模板时都会重新生成应用程序的MiniGui.cfg
,覆盖掉手工修改的内容,这个问题我不知道算是miniStudio的bug,还是有意这么设计的,有点坑爹,目前没有找到解决办法。所以在做UI设计的时候,一定要注意了。
设置系统字体
如果你希望修默认使用TrueType字体,也要修改MiniGUI.cfg
,如下修改了应用程序的MiniGUI.cfg
miniStudio中的设置
运行效果
字库剪裁
好吧,现在我们已经基本学会在基于miniStudio,在MiniGUI应用中使用TrueType字体,那么看看这些字库文件的大小,你觉得能在嵌入式系统中用使用么?
尼玛,真是太大了,就连英文字库都有几百库,中文字库都是十几MB的体积。这么大的字库,用没办法用在资源极有限嵌入式系统中啊。
怎么办?剪裁字库.汉字字库有几千个汉字,我们的系统中可能只用到其中很少一部分,所以要想办法从TTF字库中提取项目中到的汉字的字体,生成一个更小的字库文件。
百度,google一通找,有不少字库裁剪的开源工具,我倾向于找命令行运行的工具,我找到了这个 https://github.com/googlei18n/sfntly,这是google开发的一个字库编辑工具.有java和c++两套代码,java代码中提供的sfnttool
jar包就是我们需要的工具。虽然这个项目已经不再继续开发(转到 https://github.com/rillig/sfntly),但经实际使用,sfnttool
这个工具是没问题的。
下面是sfnttool
编译过程
# 安装 java编译构建工具 ant 和 git 版本控制工具
sudo apt-get install ant git
# 克隆sfntly项目代码
git clone https://github.com/googlei18n/sfntly.git
cd sfntly/java
# 编译java代码
ant
编译完成后,会多出一个dist
夹,dist/tools/sfnttool/sfnttool.jar
就是我们需要的字库剪裁工具。
sfnttool.jar
如果你不想编译sfnttool.jar
,可以使用我编译好的jar包。
百度云盘:https://pan.baidu.com/s/1mr4jRswTv6qhfU6ynIV6MA
带--help
参数执行sfnttool.jar
可以显示sfnttool
的命令行参数
$ java -jar sfnttool.jar --help
Subset [-?|-h|-help] [-b] [-s string] fontfile outfile
Prototype font subsetter
-?,-help print this help information
-s,-string String to subset
-b,-bench Benchmark (run 10000 iterations)
-h,-hints Strip hints
-w,-woff Output WOFF format
-e,-eot Output EOT format
-x,-mtx Enable Microtype Express compression for EOT format
$ cd $tesgui_path
# 将sfnttool.jar复制到testgui项目文件夹下
$ cp $sfntly_path/java/dist/tools/sfnttool/sfnttool.jar .
# 执行 sfnttool
# 这里 "$(cat res/text/en_US.txt)" 部分命令调用linux 命令cat读取资源文件夹下的en_US.txt文件
#(这里包含了testgui项目中所有的文本),sfnttool将根据这个文本提取所有用到的汉字字体
$ java -jar sfnttool.jar -s "$(cat res/text/en_US.txt)" /usr/local/share/minigui/res/font/simkai.ttf simkai_sub.ttf
好了看看执行效果吧:
使用裁剪字库
要使用剪裁字库,一样要修改testgui/MiniGUI.cfg
,如下图,因为simkai_sub.ttf
就在testgui的当前目录下,所以这里直接填了文件名,也可以使用绝对路径。
然后你就可以运行testgui看看效果了,没变化,剪裁成功。
最后附上完整的基于MiniGUI project项目结构的字体剪裁命令行脚本工具shrink.sh
,要求sfnttool.jar
与脚本在同一文件夹下。
shrink.sh
#! /bin/bash
# 根据项目中使用到的汉字剪裁字库
# 生成的新字库文件名在原字库名后加_sub,保存在res/font
sh_folder=$(dirname $(readlink -f $0))
if [ -z $1 ] ;
then
# 没有提供命令行参数,则输出usage,退出
echo "usage: $(basename $0) fontfile"
exit -1
fi
src_font=$1
if [ ! -f $src_font ] ;
then
echo "invalid font file $src_font";
exit -1
fi
font_name=$(basename $src_font)
dst_name=${font_name%.*}_sub.${font_name##*.}
dst_font=$sh_folder/res/font/$dst_name
# 执行sfnttool 出错则返回
java -jar sfnttool.jar -s "$(cat $sh_folder/res/text/zh_CN.txt)" "$src_font" "$dst_font" || exit -1
# 显示执行成功信息
echo "subst font sucess,written to $dst_font"
echo "file size: $(ls -lh $dst_font | awk '{print $5}')"