在Android开发过程中,各个厂商通常会去修改recovery界面。在recovery显示界面上,通常有几大修改点:
- recovery字体大小
- recovery界面背景图、进度条等修改、提示语修改
- recovery支持中文显示
这篇文章,主要讲一下如何修改recovery字体大小。
1 常用的字体大小修改方法
直接上结论:
方法1:制作图片
修改recovery源码目录fonts下的png文件,如12x22.png,将它拷贝到recovery的out目录下的/res/image目录下,命令为font.png
方法2:制作字库资源
在源码目录recovery/minui下新增一个字体资源文件,如font_10x18.h,然后在graphics.c中添加这个头文件
备注:recovery会优先使用/res/image/font.png,如果该文件不存在,则使用recovery/minui下的字体文件
下面来详细讲一下这两种方法:
2 制作图片
在工程目录recovery/fonts
下,默认有12x22.png和18x32.png的文件
打开其中一个文件,里面包含了所有常见的符合和字母大小写。
但是在实际使用中,从来没有见过这两张图片资源有使用过,后来反复查看代码,发现在build/core/Makefile
里制作recovery image的地方有相关的处理。
# Select the 18x32 font on high-density devices (xhdpi and up); and
# the 12x22 font on other devices. Note that the font selected here
# can be overridden for a particular device by putting a font.png in
# its private recovery resources.
ifneq (,$(filter xxxhdpi xxhdpi xhdpi,$(recovery_density)))
recovery_font := $(call include-path-for, recovery)/fonts/18x32.png
else
recovery_font := $(call include-path-for, recovery)/fonts/12x22.png
endif
可以看到,在分辨率是xxxhdpi、xxhdpi、 xhdpi这些的时候,会使用18x32.png,其它分辨率则使用12x22.png,然后再在制作recovery image的时候,将它拷贝到res/images/font.png
。
$(hide) cp -f $(recovery_font) $(TARGET_RECOVERY_ROOT_OUT)/res/images/font.png
然后在recovery源码目录下recovery/minui/graphics.c
中会处理这个图片:
static void gr_init_font(void)
{
gr_font = calloc(sizeof(*gr_font), 1);
int res = res_create_alpha_surface("font", &(gr_font->texture));
if (res == 0) {
// The font image should be a 96x2 array of character images. The
// columns are the printable ASCII characters 0x20 - 0x7f. The
// top row is regular text; the bottom row is bold.
gr_font->cwidth = gr_font->texture->width / 96;
gr_font->cheight = gr_font->texture->height / 2;
} else {
printf("failed to read font: res=%d\n", res);
// fall back to the compiled-in font.
gr_font->texture = malloc(sizeof(*gr_font->texture));
gr_font->texture->width = font.width;
gr_font->texture->height = font.height;
gr_font->texture->row_bytes = font.width;
gr_font->texture->pixel_bytes = 1;
unsigned char* bits = malloc(font.width * font.height);
gr_font->texture->data = (void*) bits;
unsigned char data;
unsigned char* in = font.rundata;
while((data = *in++)) {
memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
bits += (data & 0x7f);
}
gr_font->cwidth = font.cwidth;
gr_font->cheight = font.cheight;
}
}
可以看到,在初始化字体的函数gr_init_font
中,而int res = res_create_alpha_surface(“font”, &(gr_font->texture));这句就是去读取res/images/font.png
,读取成功就设置字体的宽高。
因此在修改图片的方法中,只需要得到我们需要的字体大小的图片即可。
最简单的方法,使用ps打开任意一个png文件,然后将图片大小修改成对应的大小即可。修改后,如不想修改build/core/Makefile
,可以将图片直接放在res/images/下,并命名为font.png。
3 制作字库资源
在上面的初始化字体函数gr_init_font
中,我们也可以看到,在读取不到png资源的时候,会走到else分支,而这个分支就会使用默认定义好的字符集“font",如recovery/minui/roboto_10x18.h
文件。
我们看看这个文件长啥样:
struct {
unsigned width;
unsigned height;
unsigned cwidth;
unsigned cheight;
unsigned char rundata[];
} font = {
.width = 960,
.height = 18,
.cwidth = 10,
.cheight = 18,
.rundata = {
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82,
0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06,
0x84,0x0a,0x81,0x03,0x88,0x04,0x84,0x04,0x88,0x04,0x84,0x06,0x84,0x1e,0x81,
0x0e,0x81,0x0a,0x84,0x06,0x84,0x07,0x82,0x05,0x85,0x07,0x84,0x04,0x86,0x04,
这就是系统自带的默认roboto字符集。它不是简单地由一系列图像RGB值组合起来,那么它是怎么制作的呢?
首先,我们要用到BMFont软件,它是一款免费的cocos2d-x位图字体生成工具,许多游戏里都用它产生字库。下载并打开,在主界面右侧选一个你想要的字库,然后在Option->Font Setting菜单里面调节字体、Size与Height。(Size对应头文件里的cwidth,这里我选了10;Height对应cheight占Height的半分比,这里我选了100%。);
然后在Option->Export Options调节Width与Height(就是头文件里的Width与Height,这里我设置成了960和18);最下面File format里的font descriptor选Text,Textures选png。
最后在Option->save bitmap font as … 导出文件,格式选.fnt。做完这一步之后,会得到两个文件:.fnt与.png文件,我们需要后面的那个png文件作为图片字库,生成最终的头文件。 然后切换到Linux系统下,安装gimp(sudo apt-get install gimp),并使用gimp打开那个png文件,在File->export as…导出文件,后缀选择c文件,(注意不要选h文件!),然后会弹出一个“导出为c源码”的框,注意里面的复选框一个都不要选,不透明度调节成100%,
其他不需要改动,然后单击“导出”按钮,最后得到一个c文件。
接下来我们尝试生成字符集头文件。首先把那个c文件后缀名改成.h(比如由"tmp.c"改成tmp.h")。然后,将文件放到android工程下的bootable/ecovery/minui
目录下,并打开mkfont.c文件,在头文件的位置加上
#include "tmp.h"
然后把mkfonts.c文件里的"x+=3"全部变成"x+=gimp_image.bytes_per_pixel"。最后执行:
gcc mkfont.c
./a.out > font.h
然后就可以看到我们生成的字符集头文件font.h。
最后,只需要在graphics.c开头include我们的font.h,recovery模式就可以使用我们自己定制的字库了。
:
gcc mkfont.c
./a.out > font.h
然后就可以看到我们生成的字符集头文件font.h。
最后,只需要在graphics.c开头include我们的font.h,recovery模式就可以使用我们自己定制的字库了。