简单记录下,展讯的模块关机充电动画部分是由 miniui 开发的,本次修改内容为将竖屏显示修改为横屏显示,代码路径如下:
vendor/sprd/proprietories-source/charge/ui.c
vendor/sprd/proprietories-source/charge/images
代码中首先会初始化资源,也就是根据分辨率选择对应的图片。。
static void res_init(void)
{
int i = 0;
int j = 0;
int k = 0;
char *temp;
switch (res_pixel_identify()){
case SIZE_360X640:
temp = gm;
break;
case SIZE_480X800:
temp = gh;
break;
case SIZE_720X1280:
temp = gxh;
break;
case SIZE_1080X1920:
temp = gxxh;
break;
case SIZE_1440X2560:
temp = gxxxh;
break;
default:
temp = gm;
break;
}
...
return;
}
如果不清楚的可通过 adb 查看,
adb shell wm size
所用的设备则为 gxxh,因此需要将对应的图片资源旋转至合适的角度。具体怎么看从哪旋转的话,就是先看好横屏后的方向,然后推敲由竖屏需要旋转多少度才能到现在的度数。
其次需要在 ui.c 中设置图片文件的位置,数字部分由以下代码设置。
static void draw_text_picture(int level)
{
int hundred = 0;
int ten = 0;
int bit = 0;
int width = gr_get_width(gNumber[0]);
int height = gr_get_height(gNumber[0]);
int capacity_w = gr_get_width(gPercent);
int catpcity_h = gr_get_height(gPercent);
int progressWidth = gr_get_width(gProgressBarEmpty);
int progressHeight = gr_get_height(gProgressBarEmpty);
int dx = (gr_fb_width() - progressWidth - 2*width)/2;
int dy = gr_fb_height()/2 /*- gr_get_height(gProgressBarIndeterminate[0])/2 - height *2*/;
LOGE("get fb width = %d hight = %d dx = %d dy =%d\n", gr_fb_width(), gr_fb_height(),dx,dy);
hundred = level/100;
ten = (level%100)/10;
bit = level%10;
if(hundred == 1)
gr_blit(gNumber[hundred],0,0,width,height,dx,dy - 2*height);
if(level >= 10)
gr_blit(gNumber[ten],0,0,width,height,dx,dy - height);
gr_blit(gNumber[bit],0,0,width,height,dx, dy);
gr_blit(gPercent,0,0,capacity_w,catpcity_h,dx, dy + height);
}
其中注意到,图片的位置都是由 gr_blit 的函数控制的,于是百度了下顺便记录一下。但是有一点很坑的地方就是这个x,y坐标。
/*
*source:被画的图片数据
*sx/sy:这是一个坐标对,表示从哪个点开始画,这是一个相对dx、dy的数据
*w/h:source的长和宽
*dx/dy:开始从哪个点开始画
*/
void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
if (source == NULL) return;
if (gr_draw->pixel_bytes != source->pixel_bytes) {
printf("gr_blit: source has wrong format\n");
return;
}
dx += overscan_offset_x;
dy += overscan_offset_y;
if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;//指向将要画出的数据
unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;//指向将要画到哪里
int i;
//将数据复制过去
for (i = 0; i < h; ++i) {
memcpy(dst_p, src_p, w * source->pixel_bytes);
src_p += source->row_bytes;
dst_p += gr_draw->row_bytes;
}
}
Android提供了一个库minui用于简单的UI输出,源码在factory/src/minui中,
gr_init()和gr_font_size()为minui库提供方法,
gr_init()为UI输出作准备,
gr_font_size()获得字体大小
res_create_surface()为minui库中提供,用于将一张图片生成一个surface
常用API:
- int gr_init(void); /* 初始化图形显示,主要是打开设备、分配内存、初始化一些参数 */
- void gr_exit(void); /* 注销图形显示,关闭设备并释放内存 */
- gr_font_size() 将字体对应的surface长宽赋值给char_width和char_height
- int gr_fb_width(void); /* 获取屏幕的宽度 */
- int gr_fb_height(void); /* 获取屏幕的高度 */
- gr_pixel *gr_fb_data(void); /* 获取显示数据缓存的地址 */
- void gr_flip(void); /* 刷新显示内容 */
- void gr_fb_blank(bool blank); /* 清屏 */
- void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a); /* 设置字体颜色 */
- void gr_fill(int x, int y, int w, int h); /* 填充矩形区域,参数分别代表起始坐标、矩形区域大小 */
- int gr_text(int x, int y, const char *s); /* 显示字符串 */
- int gr_measure(const char *s); /* 获取字符串在默认字库中占用的像素长度 */
- void gr_font_size(int *x, int *y); /* 获取当前字库一个字符所占的长宽 */
- void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy); /* 填充由source指定的图片 */
- unsigned int gr_get_width(gr_surface surface); /* 获取图片宽度 */
- unsigned int gr_get_height(gr_surface surface); /* 获取图片高度 */
- /* 根据图片创建显示资源数据,name为图片在mk文件指定的相对路径 */
- int res_create_surface(const char* name, gr_surface* pSurface);
- void res_free_surface(gr_surface surface); /* 释放资源数据 */
关于 miniui 的可以参考 miniui详解 - 知乎