欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

程序员文章站 2022-05-30 14:18:09
...

CSDN好像有问题,文章中图片太多无法继续增加图片,所以文章分两个部分:上半部分地址:
《minigui 3.2.0:基于miniStudio应用TrueType字体的过程(1)》,下半部分用MarkdownPad2编辑,使用MarkdownPad2内置的图床,可能显示图片会有些慢。

TrueType字体的边缘锯齿

上节我们已经成功在miniStudio中加载了TrueType字体,但是如果你仔细看,发现这个字体效果有问题,有明显边缘锯齿和和残点,太丑陋啦,不可忍呐!
minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

这个问题的形成原因在这里不展开说明了,MiniGUI的开发手册中有14.7《字体的渲染特效》专门讲到了程序解决这个问题的办法。

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

这里是说明如何在编程时通过设置逻辑字体风格(style)来指定字体的渲染特效消除锯齿的,对应到miniStudio图像界面中就是在选择字体的(style)

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

OK,边缘锯齿问题解决!

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

运行使用了TrueType的MiniGUI应用程序

经过上一节,我们已经成功在miniStudio中对控件设置了TrueType字体。于是满心欢喜的保存模板,去eclipse中运行程序看看效果。。。

然而冷冰冰的现实,又让我的心情跌到的谷底。。。

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

我认字不多,但你不要骗我,边缘锯齿是没有了,但楷体不长这样啊!

为什么miniStudio中明明设置成功的字体,到程序运行的时候就变卦了呢?为这个问题我又是好一顿折腾。

打开testgui项目的MiniGUI.cfg,

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

我明白了原因,应用程序的MiniGUI.cfg[truetypefonts]字段没有同步更新,而通过前面的关于MiniGUI 的运⾏时配置选项的说明,我们知道MiniGUI应用程序启动时首先是找自己当前文件夹下的MiniGUI.cfg。这里没有指定TrueType字体,即使MiniGUI系统配置文件中有指定,也没有办法加载字体。

于是我手工将/usr/local/etc/MiniGUI.cfg[truetypefonts]字段的内容复制到/testgui/path/MiniGui.cfg中对应的[truetypefonts]字段
minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

再运行程序,成功。

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

你以为这就完了么?NO,如果你再打开miniStudio,编辑模板文件保存后,你会发现/testgui/path/MiniGui.cfg的内容又恢复了原样!

也就是说miniStudio每次保存模板时都会重新生成应用程序的MiniGui.cfg,覆盖掉手工修改的内容,这个问题我不知道算是miniStudio的bug,还是有意这么设计的,有点坑爹,目前没有找到解决办法。所以在做UI设计的时候,一定要注意了。

设置系统字体

如果你希望修默认使用TrueType字体,也要修改MiniGUI.cfg,如下修改了应用程序的MiniGUI.cfg

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

miniStudio中的设置

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

运行效果

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

字库剪裁

好吧,现在我们已经基本学会在基于miniStudio,在MiniGUI应用中使用TrueType字体,那么看看这些字库文件的大小,你觉得能在嵌入式系统中用使用么?

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

尼玛,真是太大了,就连英文字库都有几百库,中文字库都是十几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

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

$ 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

好了看看执行效果吧:

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

使用裁剪字库

要使用剪裁字库,一样要修改testgui/MiniGUI.cfg,如下图,因为simkai_sub.ttf就在testgui的当前目录下,所以这里直接填了文件名,也可以使用绝对路径。

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

然后你就可以运行testgui看看效果了,没变化,剪裁成功。

minigui 3.2.0:基于miniStudio应用TrueType字体的过程(2)-字体边缘锯齿,字库剪裁

最后附上完整的基于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}')"