KT26-0607_AC695n-BTE-SDK312/cpu/br23/ui_driver/interface/ui_platform.c
2026-06-07 19:38:16 +08:00

4121 lines
120 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ui/includes.h"
#include "timer.h"
#include "asm/crc16.h"
#include "ui/lcd_spi/lcd_drive.h"
#include "ascii.h"
#include "font/font_textout.h"
#include "res/rle.h"
#include "res/resfile.h"
#include "ui/res_config.h"
#include "app_config.h"
#include "dev_manager.h"
#include "app_task.h"
#include "smartbox/smartbox_task.h"
#include "fs/fs.h"
#if TCFG_SPI_LCD_ENABLE
#define UI_DEBUG 0
/* #define UI_BUF_CALC */
#if (UI_DEBUG == 1)
#define UI_PUTS puts
#define UI_PRINTF printf
#else
#define UI_PUTS(...)
#define UI_PRINTF(...)
#endif
#define _RGB565(r,g,b) (u16)((((r)>>3)<<11)|(((g)>>2)<<5)|((b)>>3))
#define UI_RGB565(c) \
_RGB565((c>>16)&0xff,(c>>8)&0xff,c&0xff)
#define TEXT_MONO_CLR 0x555aaa
#define TEXT_MONO_INV 0xaaa555
#define RECT_MONO_CLR 0x555aaa
#define BGC_MONO_SET 0x555aaa
struct fb_map_user {
u16 xoffset;
u16 yoffset;
u16 width;
u16 height;
u8 *baddr;
u8 *yaddr;
u8 *uaddr;
u8 *vaddr;
u8 transp;
u8 format;
};
struct fb_var_screeninfo {
u16 s_xoffset; //显示区域x坐标
u16 s_yoffset; //显示区域y坐标
u16 s_xres; //显示区域宽度
u16 s_yres; //显示区域高度
u16 v_xoffset; //屏幕的虚拟x坐标
u16 v_yoffset; //屏幕的虚拟y坐标
u16 v_xres; //屏幕的虚拟宽度
u16 v_yres; //屏幕的虚拟高度
u16 rotate;
};
struct window_head {
u32 offset;
u32 len;
u32 ptr_table_offset;
u16 ptr_table_len;
u16 crc_data;
u16 crc_table;
u16 crc_head;
};
struct ui_file_head {
u8 res[16];
u8 type;
u8 window_num;
u16 prop_len;
u8 rotate;
u8 rev[3];
};
struct ui_load_info ui_load_info_table[] = {
#if UI_WATCH_RES_ENABLE
{1, NULL, NULL},
{2, RES_PATH"sidebar/sidebar.sty", NULL},
#endif
{-1, NULL, NULL},
};
static u32 ui_rotate = false;
static u32 ui_hori_mirror = false;
static u32 ui_vert_mirror = false;
static int malloc_cnt = 0;
static FILE *ui_file = NULL;
static FILE *ui_file1 = NULL;
static FILE *ui_file2 = NULL;
static int ui_file_len = 0;
static int open_resource_file();
void select_strfile(u8 index);
void select_resfile(u8 index);
static const struct ui_platform_api br23_platform_api;
struct ui_priv {
struct ui_platform_api *api;
struct lcd_interface *lcd;
int window_offset;
struct lcd_info info;
};
static struct ui_priv priv ALIGNED(4);
#define __this (&priv)
#ifdef UI_BUF_CALC
struct buffer {
struct list_head list;
u8 *buf;
int size;
};
struct buffer buffer_used = {0};
#endif
void *br23_malloc(int size)
{
void *buf;
malloc_cnt++;
buf = (void *)malloc(size);
/* printf("platform_malloc : 0x%x, %d\n", buf, size); */
#ifdef UI_BUF_CALC
struct buffer *new = (struct buffer *)malloc(sizeof(struct buffer));
new->buf = buf;
new->size = size;
list_add_tail(new, &buffer_used);
printf("platform_malloc : 0x%x, %d\n", buf, size);
struct buffer *p;
int buffer_used_total = 0;
list_for_each_entry(p, &buffer_used.list, list) {
buffer_used_total += p->size;
}
printf("used buffer size:%d\n\n", buffer_used_total);
#endif
return buf;
}
void br23_free(void *buf)
{
/* printf("platform_free : 0x%x\n",buf); */
free(buf);
malloc_cnt--;
#ifdef UI_BUF_CALC
struct buffer *p, *n;
list_for_each_entry_safe(p, n, &buffer_used.list, list) {
if (p->buf == buf) {
printf("platform_free : 0x%x, %d\n", p->buf, p->size);
__list_del_entry(p);
free(p);
}
}
int buffer_used_total = 0;
list_for_each_entry(p, &buffer_used.list, list) {
buffer_used_total += p->size;
}
printf("used buffer size:%d\n\n", buffer_used_total);
#endif
}
int ui_platform_ok()
{
return (malloc_cnt == 0);
}
static void draw_rect_range_check(struct rect *r, struct fb_map_user *map)
{
if (r->left < map->xoffset) {
r->left = map->xoffset;
}
if (r->left > (map->xoffset + map->width)) {
r->left = map->xoffset + map->width;
}
if ((r->left + r->width) > (map->xoffset + map->width)) {
r->width = map->xoffset + map->width - r->left;
}
if (r->top < map->yoffset) {
r->top = map->yoffset;
}
if (r->top > (map->yoffset + map->height)) {
r->top = map->yoffset + map->height;
}
if ((r->top + r->height) > (map->yoffset + map->height)) {
r->height = map->yoffset + map->height - r->top;
}
ASSERT(r->left >= map->xoffset);
ASSERT(r->top >= map->yoffset);
ASSERT((r->left + r->width) <= (map->xoffset + map->width));
ASSERT((r->top + r->height) <= (map->yoffset + map->height));
}
/* 透明色: 16bits 0x55aa 0101 0xxx 1011 01xx 0101 0xxx
* 24bits 0x50b450 0101 0000 1011 0100 0101 0000 , 80 180 80
* */
void __font_pix_copy(struct draw_context *dc, int format, struct fb_map_user *map, u8 *pix, struct rect *draw, int x, int y,
int height, int width, int color)
{
int i, j, h;
u16 osd_color;
u32 size;
osd_color = (format == DC_DATA_FORMAT_OSD8) || (format == DC_DATA_FORMAT_OSD8A) ? color & 0xff : color & 0xffff ;
for (j = 0; j < (height + 7) / 8; j++) { /* 纵向8像素为1字节 */
for (i = 0; i < width; i++) {
if (((i + x) >= draw->left)
&& ((i + x) <= (draw->left + draw->width - 1))) { /* x在绘制区域要绘制 */
u8 pixel = pix[j * width + i];
int hh = height - (j * 8);
if (hh > 8) {
hh = 8;
}
for (h = 0; h < hh; h++) {
if (((y + j * 8 + h) >= draw->top)
&& ((y + j * 8 + h) <= (draw->top + draw->height - 1))) { /* y在绘制区域要绘制 */
u16 clr = pixel & BIT(h) ? osd_color : 0;
if (clr) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, x + i, y + j * 8 + h, clr);
}
}
}
} /* endof for h */
}
}/* endof for i */
}/* endof for j */
}
static int image_str_size_check(struct draw_context *dc, int page_num, const char *txt, int *width, int *height)
{
u16 id = ((u8)txt[1] << 8) | (u8)txt[0];
u16 cnt = 0;
struct image_file file;
int w = 0, h = 0;
while (id != 0x00ff) {
select_resfile(dc->prj);
if (open_image_by_id(NULL, &file, id, page_num) != 0) {
return -EFAULT;
}
w += file.width;
cnt += 2;
id = ((u8)txt[cnt + 1] << 8) | (u8)txt[cnt];
}
h = file.height;
*width = w;
*height = h;
return 0;
}
void platform_putchar(struct font_info *info, u8 *pixel, u16 width, u16 height, u16 x, u16 y)
{
__font_pix_copy(info->dc, info->disp.format,
(struct fb_map_user *)info->disp.map,
pixel,
(struct rect *)info->disp.rect,
(s16)x,
(s16)y,
height,
width,
info->disp.color);
}
struct file_dev {
const char *logo;
const char *root_path;
};
struct file_browser {
int show_mode;
struct rect r;
struct vfscan *fscan;
/* struct server *server; */
struct ui_file_browser bro;
struct file_dev dev;//支持三个设备
};
static int check_file_ext(const char *ext_table, const char *ext)
{
const char *str;
for (str = ext_table; *str != '\0'; str += 3) {
if (0 == ASCII_StrCmpNoCase(ext, str, 3)) {
return true;
}
}
return false;
}
static const u8 MUSIC_SCAN_PARAM[] = "-t"
"MP1MP2MP3"
" -sn -d"
;
static int platform_file_get_dev_total()
{
return dev_manager_get_total(1);
}
static void platform_file_browser_get_dev_info(struct ui_file_browser *_bro, u8 index)
{
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
struct file_dev *file_dev;//支持三个设备
if (!bro) {
return;
}
struct __dev *dev = dev_manager_find_by_index(index, 0);//storage_dev_find_by_index(index);
if (dev) {
file_dev = &bro->dev;
file_dev->logo = dev_manager_get_logo(dev);//获取设备logo
file_dev->root_path = dev_manager_get_root_path_by_logo(dev);//获取设备路径
}
}
static struct ui_file_browser *platform_file_browser_open(struct rect *r,
const char *path, const char *ftype, int show_mode)
{
int err;
struct file_browser *bro;
struct __dev *dev = 0;
bro = (struct file_browser *)malloc(sizeof(*bro));
if (!bro) {
return NULL;
}
bro->bro.file_number = 0;
bro->show_mode = show_mode;
if (!path) {
dev = dev_manager_find_active(0);///storage_dev_last();//获取最后一个设备的路径
if (!dev) {
free(bro);
return NULL;
}
path = dev_manager_get_root_path_by_logo(dev);//dev->root_path;
}
if (!ftype) {
ftype = MUSIC_SCAN_PARAM;
}
bro->fscan = fscan(path, ftype, 9);
bro->bro.dev_num = dev_manager_get_total(1);//获取在线设备总数
if (bro->fscan) {
bro->bro.file_number = bro->fscan->file_number;
if (bro->bro.file_number == 0) {
return &bro->bro;
}
}
if (r) {
memcpy(&bro->r, r, sizeof(struct rect));
}
return &bro->bro;
__err:
fscan_release(bro->fscan);
free(bro);
return NULL;
}
static void platform_file_browser_close(struct ui_file_browser *_bro)
{
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
if (!bro) {
return;
}
if (bro->fscan) {
fscan_release(bro->fscan);
}
free(bro);
}
static int platform_get_file_attrs(struct ui_file_browser *_bro,
struct ui_file_attrs *attrs)
{
int i, j;
struct vfs_attr attr;
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
if (!bro->fscan) {
return -ENOENT;
}
FILE *file = fselect(bro->fscan, FSEL_BY_NUMBER, attrs->file_num + 1);
if (!file) {
return -ENOENT;
}
attrs->format = "ascii";
fget_attrs(file, &attrs->attr);
/* printf(" attr = %x, fsize = %x,sclust = %x\n",attrs->attr.attr,attrs->attr.fsize,attrs->attr.sclust); */
struct sys_time *time;
time = &(attrs->attr.crt_time);
/* printf("y =%d m =%d d = %d,h = %d ,m = %d ,s =%d\n",time->year,time->month,time->day,time->hour,time->min,time->sec); */
time = &(attrs->attr.wrt_time);
/* printf("y =%d m =%d d = %d,h = %d ,m = %d ,s =%d\n",time->year,time->month,time->day,time->hour,time->min,time->sec); */
int len = fget_name(file, (u8 *)attrs->fname, 16);//长文件获取有问题
if (len < 0) {
fclose(file);
return -EINVAL;
}
for (i = 0; i < len; i++) {
if ((u8)attrs->fname[i] >= 0x80) {
attrs->format = "uft16";
goto _next;
}
}
/* ASCII_ToUpper(attrs->fname, strlen(attrs->fname)); */
_next:
#if 0//文件系统接口不完善,临时解决
for (i = 0; i < len; i++) {
if (attrs->fname[i] == '.') {
break;
}
}
if (i == len) {
attrs->ftype = UI_FTYPE_DIR;
} else {
char *ext = attrs->fname + i + 1;
if (check_file_ext("JPG", ext)) {
attrs->ftype = UI_FTYPE_IMAGE;
} else if (check_file_ext("MOVAVI", ext)) {
attrs->ftype = UI_FTYPE_VIDEO;
} else if (check_file_ext("MP3WMAWAV", ext)) {
attrs->ftype = UI_FTYPE_AUDIO;
} else {
attrs->ftype = UI_FTYPE_UNKNOW;
}
}
#else
/* printf("name = %d %d \n",strlen(attrs->fname),len); */
/* put_buf(attrs->fname,len); */
if (attrs->attr.attr & F_ATTR_DIR) {
attrs->ftype = UI_FTYPE_DIR;
} else {
char *ext = attrs->fname + strlen(attrs->fname) - 3;
if (check_file_ext("JPG", ext)) {
attrs->ftype = UI_FTYPE_IMAGE;
} else if (check_file_ext("MOVAVI", ext)) {
attrs->ftype = UI_FTYPE_VIDEO;
} else if (check_file_ext("MP3WMAWAV", ext)) {
attrs->ftype = UI_FTYPE_AUDIO;
} else {
attrs->ftype = UI_FTYPE_UNKNOW;
}
}
#endif
fclose(file);
return 0;
}
static int platform_set_file_attrs(struct ui_file_browser *_bro,
struct ui_file_attrs *attrs)
{
int attr = 0;
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
if (!bro->fscan) {
return -ENOENT;
}
FILE *file = fselect(bro->fscan, FSEL_BY_NUMBER, attrs->file_num + 1);
if (!file) {
return -EINVAL;
}
fget_attr(file, &attr);
if (attrs->attr.attr & F_ATTR_RO) {
attr |= F_ATTR_RO;
} else {
attr &= ~F_ATTR_RO;
}
fset_attr(file, attr);
fclose(file);
return 0;
}
static void *platform_open_file(struct ui_file_browser *_bro,
struct ui_file_attrs *attrs)
{
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
if (!bro->fscan) {
return NULL;
}
return fselect(bro->fscan, FSEL_BY_NUMBER, attrs->file_num + 1);
}
static int platform_delete_file(struct ui_file_browser *_bro,
struct ui_file_attrs *attrs)
{
struct file_browser *bro = container_of(_bro, struct file_browser, bro);
if (!bro->fscan) {
return -EINVAL;
}
FILE *file = fselect(bro->fscan, FSEL_BY_NUMBER, attrs->file_num + 1);
if (!file) {
return -EFAULT;
}
fdelete(file);
return 0;
}
void test_browser()
{
struct ui_file_browser *browser = NULL;
static struct ui_file_attrs attrs = {0};
if (!browser) {
browser = platform_file_browser_open(NULL, NULL, MUSIC_SCAN_PARAM, 0);
}
if (browser) {
printf("file num = %d \n", browser->file_number);
platform_get_file_attrs(browser, &attrs);
printf("format =%s name =%s type = %x \n", attrs.format, attrs.fname, attrs.ftype);
platform_delete_file(browser, &attrs);
attrs.file_num ++;
if (attrs.file_num >= browser->file_number) {
attrs.file_num = 0;
}
}
}
static void *br23_set_timer(void *priv, void (*callback)(void *), u32 msec)
{
return (void *)sys_timer_add(priv, callback, msec);
}
static int br23_del_timer(void *fd)
{
if (fd) {
sys_timer_del((int)fd);
}
return 0;
}
u32 __attribute__((weak)) set_retry_cnt()
{
return 10;
}
const char *WATCH_VERSION_LIST = {
"W001"
};
/* static const char *WATCH_STY_CHECK_LIST[] = { */
/* RES_PATH"JL/JL.sty", */
/* RES_PATH"watch/watch.sty", */
/* RES_PATH"watch1/watch1.sty", */
/* RES_PATH"watch2/watch2.sty", */
/* RES_PATH"watch3/watch3.sty", */
/* RES_PATH"watch4/watch4.sty", */
/* RES_PATH"watch5/watch5.sty", */
/* }; */
#define WATCH_ITEMS_LIMIT 40
#define BGP_ITEMS_LIMIT (WATCH_ITEMS_LIMIT + 10)//(确保 >= WATCH_ITEMS_LIMIT就可以)
static u8 watch_style;
static u8 watch_items;
static volatile u8 watch_update_over = 0;
static char *watch_res[WATCH_ITEMS_LIMIT] = {0};
static char *watch_bgp_related[WATCH_ITEMS_LIMIT] = {0};
static char *watch_bgp[BGP_ITEMS_LIMIT] = {0};
static u8 watch_bgp_items;
static char *watch_bgpic_path = NULL;
extern u8 smartbox_eflash_flag_get(void);
extern u8 smartbox_eflash_update_flag_get(void);
extern void smartbox_eflash_flag_set(u8 eflash_state_type);
static int watch_mem_bgp_related();
u32 watch_bgp_get_nums()
{
return watch_bgp_items;
}
char *watch_bgp_get_item(u8 sel_item)
{
if (sel_item >= watch_bgp_items) {
printf("\n\n\nwatch_bgp items overflow %d\n\n\n\n", sel_item);
return NULL;
}
return watch_bgp[sel_item];
}
char *watch_bgp_add(char *bgp)
{
char *root_path = RES_PATH;
char *new_bgp_item = NULL;
u32 len;
u32 i;
if ((watch_bgp_items + 1) >= BGP_ITEMS_LIMIT) {
printf("\n\n\nwatch_bgp items overflow %d\n\n\n\n", watch_bgp_items);
return NULL;
}
len = strlen(bgp) + strlen(root_path) + 1;
new_bgp_item = malloc(len);
if (new_bgp_item == NULL) {
printf("\n\n\nwatch_bgp items malloc err %d\n\n\n\n", len);
return NULL;
}
ASCII_ToLower(bgp, strlen(bgp));
strcpy(new_bgp_item, root_path);
/* strcpy(&new_bgp_item[strlen(root_path)], &bgp[1]); */
strcpy(&new_bgp_item[strlen(root_path)], bgp);
new_bgp_item[len - 1] = '\0';
//如果已经存在这个背景图片路径,则直接返回对应的地址
for (i = 0; i < watch_bgp_items; i++) {
/* printf("num %s\n", watch_bgp[i]); */
if (strncmp(new_bgp_item, watch_bgp[i], strlen(new_bgp_item)) == 0) {
free(new_bgp_item);
new_bgp_item = watch_bgp[i];
printf("already has %s\n", new_bgp_item);
return new_bgp_item;
}
}
watch_bgp[watch_bgp_items] = new_bgp_item;
watch_bgp_items++;
printf("add new_bgp_item succ %d, %s\n", watch_bgp_items, new_bgp_item);
return new_bgp_item;
}
int watch_bgp_del(char *bgp)
{
u32 i;
char watch_bgp_item[64];
u32 cur_items = watch_bgp_items;
char *root_path = RES_PATH;
char *bgp_item = NULL;
ASSERT(((strlen(bgp) + strlen(root_path) + 1) < sizeof(watch_bgp_item)), "bgp err name0 %s\n", bgp);
ASCII_ToLower(bgp, strlen(bgp));
strcpy(watch_bgp_item, root_path);
/* strcpy(&watch_bgp_item[strlen(root_path)], &bgp[1]); */
strcpy(&watch_bgp_item[strlen(root_path)], bgp);
watch_bgp_item[strlen(bgp) + strlen(root_path)] = '\0';
printf("watch_bgp_item %s\n", watch_bgp_item);
for (i = 0; i < cur_items; i++) {
if (strncmp(watch_bgp_item, watch_bgp[i], strlen(watch_bgp_item)) == 0) {
bgp_item = watch_bgp[i];
watch_bgp[i] = NULL;
free(bgp_item);
watch_bgp_items--;
break;
}
}
if (bgp_item == NULL) {
printf("can not find bgp_item %s\n", watch_bgp_item);
return -1;
}
for (; i < cur_items; i++) {
if (watch_bgp[i + 1] != NULL) {
watch_bgp[i] = watch_bgp[i + 1];
} else {
watch_bgp[i] = NULL;
break;
}
}
//del related item
cur_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
for (i = 0; i < cur_items; i++) {
if (bgp_item == watch_bgp_related[i]) {
watch_bgp_related[i] = NULL;
}
}
for (i = 0; i < cur_items; i++) {
printf("cur related items %d, %s\n", i, watch_bgp_related[i]);
}
for (i = 0; i < watch_bgp_items; i++) {
printf("cur bgp items %d, %s\n", i, watch_bgp[i]);
}
return 0;
}
//替换背景图片,(1)如果某个表盘没有背景图片,则增加,(2)如果有就替换
//如果被替换的这个背景图片已经不关联任何表盘则将它从表watch_bgp删除
int watch_bgp_set_related(char *bgp, u8 cur_watch, u8 del)
{
u32 i;
u32 cur_items;
char *root_path = RES_PATH;
char *bgp_item = NULL;
char *new_bgp_item = NULL;
u32 total_relate_items;
char old_bgp[16];
u32 len;
total_relate_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
if (cur_watch >= total_relate_items) {
printf("\n\n\nwatch_bgp_related items overflow %d\n\n\n\n", cur_watch);
return -1;
}
//提取旧的背景图片名字
if (watch_bgp_related[cur_watch]) {
bgp_item = watch_bgp_related[cur_watch];
len = strlen(bgp_item) - strlen(root_path) + 1;
if (len >= sizeof(old_bgp)) {
return -1;
}
memcpy(old_bgp, &bgp_item[strlen(root_path)], len);
printf("old bpg %s\n", old_bgp);
}
if (bgp != NULL) {
new_bgp_item = watch_bgp_add(bgp);
if (new_bgp_item == NULL) {
printf("add bgp item err %s\n", bgp);
return -1;
}
}
//如果没有背景图片
if (watch_bgp_related[cur_watch] == NULL) {
watch_bgp_related[cur_watch] = new_bgp_item;
/* printf("a1\n"); */
} else {
bgp_item = watch_bgp_related[cur_watch];
watch_bgp_related[cur_watch] = new_bgp_item;
cur_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
/* printf("a2 %s\n", bgp_item); */
for (i = 0; i < cur_items; i++) {
if (bgp_item == watch_bgp_related[i]) {
/* printf("a3 %d\n", i); */
break;
}
}
if ((i == cur_items) && del) { //被替换的这个背景图片已经不关联任何表盘
/* printf("a4\n"); */
watch_bgp_del(old_bgp);
}
}
watch_mem_bgp_related();
return 0;
}
//根据某个表盘获取对应的背景图片
char *watch_bgp_get_related(u8 cur_watch)
{
u32 total_relate_items;
total_relate_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
if (cur_watch >= total_relate_items) {
printf("\n\n\nwatch_bgp_related items overflow %d\n\n\n\n", cur_watch);
return NULL;
}
return watch_bgp_related[cur_watch];
}
int watch_bgp_related_del_all(char *bgp)
{
watch_bgp_del(bgp);
watch_mem_bgp_related();
return 0;
}
int watch_get_style_by_name(char *name)
{
u32 i;
u32 ret;
printf("watch find %s\n", name);
for (i = 0; i < watch_items; i++) {
/* printf("watch finding %s\n", watch_res[i]); */
if (strncmp(name, watch_res[i], strlen(name)) == 0) {
printf("find watch style %d, %s\n\n\n", i, watch_res[i]);
return i;
}
}
printf("watch find faile\n");
return -1;
}
#define WATCH_MEM_BGP 0x55aa66bb
static u32 wmem_last = 0;
static u32 wmem_area_num = 0;
static void *wmem_file = NULL;
int watch_mem_new(u32 area)
{
wmem_last = area;
wmem_area_num++;
return 0;
}
void *watch_mem_open()
{
if (wmem_file == NULL) {
/* wmem_file = fopen(RES_PATH"wmem.bin", "w+"); */
wmem_file = fopen("storage/sd1/C/wmem.bin", "w+");
}
return wmem_file;
}
void watch_mem_close()
{
if (wmem_file) {
fclose(wmem_file);
wmem_file = NULL;
}
}
int watch_mem_write(u32 offset, u32 len, u8 *buf, u32 area)
{
u32 ret;
u8 tmp_buf[8];
u32 area_offset = 0;
u32 area_len = 0;
u32 find_tag = 0;
if (wmem_file == NULL) {
return -1;
}
if ((flen(wmem_file) == 0) || (wmem_area_num <= 1)) {
area_offset = 0;
} else {
do {
fseek_fast(wmem_file, area_offset, SEEK_SET);
ret = fread_fast(wmem_file, tmp_buf, 8);
if (ret != 8) {
printf("wmem find tag err end\n");
return -1;
}
memcpy(&ret, tmp_buf + 4, 4); //flag
if (ret == area) {
memcpy(&area_len, tmp_buf, 4);//len
find_tag = 1;
break;
}
memcpy(&ret, tmp_buf, 4);//len
area_offset += ret;
} while (find_tag == 0);
}
fseek_fast(wmem_file, area_offset + offset, SEEK_SET);
if (area == wmem_last) {
ret = fwrite(wmem_file, buf, len);
if (ret != len) {
return -1;
}
} else {
if ((offset + len) <= area_len) {
ret = fwrite(wmem_file, buf, len);
if (ret != len) {
return -1;
}
} else {
//要将这个区域的内容先搬迁到文件最后,使这个区域成为最后的区域
//再写数据
}
}
return 0;
}
/* static u32 wmem_test_flag = 0; */
int watch_mem_read(u32 offset, u32 len, u8 *buf, u32 area)
{
u32 area_offset = 0;
u32 area_len = 0;
u32 find_tag = 0;
u32 ret;
u8 tmp_buf[8];
if (wmem_file == NULL) {
return -1;
}
if (flen(wmem_file) == 0) {
/* wmem_test_flag = 1; */
return 0;
}
if (wmem_area_num <= 1) {
area_offset = 0;
} else {
do {
fseek_fast(wmem_file, area_offset, SEEK_SET);
ret = fread_fast(wmem_file, tmp_buf, 8);
if (ret != 8) {
printf("wmem find tag err end\n");
return -1;
}
memcpy(&ret, tmp_buf + 4, 4); //flag
if (ret == area) {
memcpy(&area_len, tmp_buf, 4);//len
find_tag = 1;
break;
}
memcpy(&ret, tmp_buf, 4);//len
area_offset += ret;
} while (find_tag == 0);
if ((offset + len) > area_len) {
return -1;
}
}
fseek_fast(wmem_file, area_offset + offset, SEEK_SET);
ret = fread_fast(wmem_file, buf, len);
if (ret != len) {
printf("wmem read err %d\n", ret);
return -1;
}
return 0;
}
static int watch_mem_bgp_related()
{
int ret = 0;
u8 *related_buf;
u32 total_relate_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
u32 len;
char *related_item;
u32 area = WATCH_MEM_BGP;
u32 i;
if (watch_bgp_items == 0) {
return -1;
}
len = 64 * (total_relate_items + 1);
related_buf = zalloc(len);
if (related_buf == NULL) {
return -1;
}
if (watch_mem_open() == NULL) {
return -1;
}
memcpy(related_buf, &len, 4);
memcpy(related_buf + 4, &area, 4);
for (i = 0; i < total_relate_items; i++) {
related_item = watch_bgp_related[i];
if (related_item) {
printf("related item : %s, %d, %d\n", related_item, strlen(related_item) + 1, i);
memcpy(&related_buf[64 + 64 * i], related_item, strlen(related_item) + 1);
}
}
ret = watch_mem_write(0, len, related_buf, area);
if (ret != 0) {
printf("watch mem werr %x\n", ret);
} else {
printf("watch mem succ\n");
}
watch_mem_close();
free(related_buf);
return ret;
}
static int watch_bgp_related_init()
{
static u8 flag = 0;
int ret = 0;
u8 *related_buf;
u32 total_relate_items = sizeof(watch_bgp_related) / sizeof(watch_bgp_related[0]);
u32 len;
char *related_item;
u32 area = WATCH_MEM_BGP;
u32 i, j;
if (flag == 0) {
watch_mem_new(area);
flag = 1;
}
if (watch_bgp_items == 0) {
return -1;
}
len = 64 * (total_relate_items + 1);
related_buf = zalloc(len);
if (related_buf == NULL) {
return -1;
}
if (watch_mem_open() == NULL) {
return -1;
}
ret = watch_mem_read(0, len, related_buf, area);
if (ret != 0) {
return -1;
}
for (i = 0; i < total_relate_items; i++) {
watch_bgp_related[i] = NULL;
related_item = &related_buf[64 + 64 * i];
if (related_item[0]) {
printf("related item : %s, %d, %d\n", related_item, strlen(related_item), i);
for (j = 0; j < watch_bgp_items; j++) {
if (strncmp(related_item, watch_bgp[j], strlen(watch_bgp[j])) == 0) {
watch_bgp_related[i] = watch_bgp[j];
printf("find bgp related %d\n", j);
break;
}
}
}
}
watch_mem_close();
free(related_buf);
return 0;
}
char *watch_get_background()
{
if (watch_bgpic_path == NULL) {
return NULL;
}
return watch_bgpic_path;
}
int watch_set_background(char *bg_pic)
{
u32 bg_strlen = strlen(bg_pic);
u32 root_path_strlen = strlen(RES_PATH);
/* if ((bg_strlen + root_path_strlen) >= sizeof(watch_bgpic_path)) { */
/* printf("set background err %d, %d\n", bg_strlen, root_path_strlen); */
/* return -1; */
/* } */
if (bg_pic == NULL) {
/* memset(watch_bgpic_path, 0, sizeof(watch_bgpic_path)); */
if (watch_bgpic_path != NULL) {
free(watch_bgpic_path);
}
watch_bgpic_path = NULL;
} else {
if (watch_bgpic_path != NULL) {
free(watch_bgpic_path);
watch_bgpic_path = NULL;
}
watch_bgpic_path = malloc(bg_strlen + root_path_strlen + 1);
if (watch_bgpic_path == NULL) {
printf("set background err %d, %d\n", bg_strlen, root_path_strlen);
return -1;
}
strcpy(watch_bgpic_path, RES_PATH);
strcpy(watch_bgpic_path + root_path_strlen, bg_pic);
watch_bgpic_path[root_path_strlen + bg_strlen] = '\0';
}
return 0;
}
void watch_update_finish()
{
printf("\n\nwatch update finish\n\n");
watch_update_over = 1;
}
int watch_get_update_status()
{
return watch_update_over;
}
char *watch_get_item(int style)
{
if (style >= watch_items) {
return NULL;
}
return watch_res[style];
}
char *watch_get_root_path()
{
return RES_PATH;
}
int watch_set_style(int style)
{
#if UI_WATCH_RES_ENABLE
/* if (style == 0) { */
/* style = 1; */
/* } */
/* if (style > sizeof(watch_res) / sizeof(watch_res[0])) { */
if (style >= watch_items) {
return false;
}
watch_style = style;
#endif
return true;
}
int watch_get_version(char *watch_item, char *version)
{
char *sty_suffix = ".sty";
char *json_suffix = ".json";
u32 tmp_strlen;
char tmp_name[64];
u32 sty_strlen;
FILE *file;
/* char *version; */
char *tver;
u32 i;
if (watch_item == NULL) {
return -1;
}
sty_strlen = strlen(sty_suffix);
tmp_strlen = strlen(watch_item);
strcpy(tmp_name, watch_item);
strcpy(&tmp_name[tmp_strlen - sty_strlen], json_suffix);
tmp_name[tmp_strlen - sty_strlen + strlen(json_suffix)] = '\0';
printf("version name %s\n", tmp_name);
file = res_fopen(tmp_name, "r");
if (!file) {
printf("open_jsonfile fail %s\n", tmp_name);
return -1;
}
memset(tmp_name, 0, sizeof(tmp_name));
res_fread(file, tmp_name, sizeof(tmp_name));
res_fclose(file);
/* printf("json buf : %s\n", tmp_name); */
tmp_name[26] = '\0';
/* version = &tmp_name[22]; */
strcpy(version, &tmp_name[22]);
return 0;
}
int watch_version_juge(char *watch_item)
{
char *sty_suffix = ".sty";
char *json_suffix = ".json";
u32 tmp_strlen;
char tmp_name[64];
u32 sty_strlen;
FILE *file;
char *version;
char *tver;
u32 i;
if (watch_item == NULL) {
return -1;
}
sty_strlen = strlen(sty_suffix);
tmp_strlen = strlen(watch_item);
strcpy(tmp_name, watch_item);
strcpy(&tmp_name[tmp_strlen - sty_strlen], json_suffix);
tmp_name[tmp_strlen - sty_strlen + strlen(json_suffix)] = '\0';
printf("version name %s\n", tmp_name);
file = res_fopen(tmp_name, "r");
if (!file) {
printf("open_jsonfile fail %s\n", tmp_name);
return -1;
}
memset(tmp_name, 0, sizeof(tmp_name));
res_fread(file, tmp_name, sizeof(tmp_name));
res_fclose(file);
/* printf("json buf : %s\n", tmp_name); */
tmp_name[26] = '\0';
version = &tmp_name[22];
/* printf("ve %s\n", version); */
for (i = 0; i < strlen(WATCH_VERSION_LIST); i += 5) {
tver = &WATCH_VERSION_LIST[i];
/* printf("ver %s, %d\n", tver, strlen(version)); */
if (strncmp(version, tver, strlen(version)) == 0) {
return 0;
}
}
printf("juge watch version err\n");
return -1;
}
int watch_set_style_by_name(char *name)
{
u32 i;
u32 ret;
printf("watch find %s\n", name);
for (i = 0; i < watch_items; i++) {
/* printf("watch finding %s\n", watch_res[i]); */
if (strncmp(name, watch_res[i], strlen(name)) == 0) {
printf("find watch style %d, %s\n\n\n", i, watch_res[i]);
ret = watch_version_juge(watch_res[i]);
if (ret != 0) {
break;
}
watch_set_style(i);
return 0;
}
}
printf("watch find faile\n");
return -1;
}
int watch_get_style()
{
return watch_style;
}
int watch_get_items_num()
{
return watch_items;
}
char *watch_get_cur_path()
{
char path[16];
u8 i;
char *tmp = &watch_res[watch_style][strlen(RES_PATH)];
path[0] = '/';
for (i = 0; i < 15; i++) {
if (tmp[i] == '/') {
break;
}
path[i + 1] = tmp[i];
putchar(tmp[i]);
}
path[i + 1] = '\0';
ASCII_ToUpper(path, strlen(path));
/* printf("cur : %s, %s, %d\n", tmp, path, i); */
/* return watch_res[watch_style]; */
return path;
}
int watch_get_cur_path_len()
{
return strlen(watch_get_cur_path()) + 1;
/* char *path = watch_res[watch_style]; */
/* u32 i; */
/* for (i = strlen(path) - 1; i > 0; i--) { */
/* if (path[i] == '/') { */
/* break; */
/* } */
/* } */
/* return i + 1; */
}
int watch_add_item(char *s)
{
char *new_item = NULL;
/* char watch_name[16]; */
u32 len;
char *suffix = ".sty";
char *root_path = RES_PATH;
char watch[64];
ASSERT(((strlen(s) + strlen(root_path) + 1) < sizeof(watch)), "err name3 %s\n", s);
/* if ((strlen(s) + strlen(root_path) + 1) >= sizeof(watch)) { */
/* printf("err name3 %s\n", s); */
/* while (1); */
/* } */
ASCII_ToLower(s, strlen(s));
strcpy(watch, root_path);
strcpy(&watch[strlen(root_path)], &s[1]);
s = watch;
printf("watch_path %s\n", s);
ASSERT(((watch_items + 1) < WATCH_ITEMS_LIMIT), "watch items overflow %d\n\n\n\n", watch_items);
/* if ((watch_items + 1) >= WATCH_ITEMS_LIMIT) { */
/* printf("watch items overflow %d\n\n\n\n", watch_items); */
/* while (1); */
/* } */
len = strlen(s) - strlen(RES_PATH);
/* printf("test len %d, %d, %d, %s, %s\n", strlen(s), strlen(RES_PATH), len, RES_PATH, s, s[len]); */
/* strcpy(watch_name, &s[strlen(s) - len]); */
/* printf("end str %s\n", watch_name); */
new_item = malloc(strlen(s) + 1 + len + strlen(suffix) + 1);
if (new_item == NULL) {
printf("watch add item fail\n");
return -1;
}
strcpy(new_item, s);
new_item[strlen(s)] = '/';
strcpy(&new_item[strlen(s) + 1], &s[strlen(s) - len]);
strcpy(&new_item[strlen(s) + 1 + len], suffix);
new_item[strlen(s) + 1 + len + strlen(suffix)] = '\0';
watch_res[watch_items] = new_item;
watch_items++;
printf("watch add item succ %d, %s\n", watch_items, new_item);
return 0;
}
int watch_del_item(char *s)
{
u32 i;
char *item;
u32 cur_items = watch_items;
char *root_path = RES_PATH;
char watch[64];
char *cur_watch = watch_res[watch_style];
ASSERT(((strlen(s) + strlen(root_path) + 1) < sizeof(watch)), "err name5 %s\n", s);
/* if ((strlen(s) + strlen(root_path) + 1) >= sizeof(watch)) { */
/* printf("err name5 %s\n", s); */
/* while (1); */
/* } */
ASCII_ToLower(s, strlen(s));
strcpy(watch, root_path);
strcpy(&watch[strlen(root_path)], &s[1]);
s = watch;
printf("watch_path %s\n", s);
if (watch_items <= 2) {
return -1;
}
for (i = 0; i < cur_items; i++) {
if (strncmp(s, watch_res[i], strlen(s)) == 0) {
item = watch_res[i];
watch_res[i] = NULL;
free(item);
watch_items--;
watch_bgp_related[i] = NULL;
break;
}
}
for (; i < cur_items; i++) {
if (watch_res[i + 1] != NULL) {
watch_res[i] = watch_res[i + 1];
watch_bgp_related[i] = watch_bgp_related[i + 1];
} else {
watch_res[i] = NULL;
watch_bgp_related[i] = NULL;
break;
}
}
for (i = 0; i < watch_items; i++) {
if (cur_watch == watch_res[i]) {
printf("del set style %d, %s\n", i, watch_res[i]);
watch_set_style(i);
break;
}
}
if (i == watch_items) {
printf("end style\n");
watch_set_style(0);
}
/* watch_mem_bgp_related(); */
for (i = 0; i < watch_items; i++) {
printf("cur watch item %d, %s\n", watch_items, watch_res[i]);
}
return 0;
}
void watch_select_mem()
{
#if UI_WATCH_RES_ENABLE
syscfg_write(VM_WATCH_SELECT, &watch_style, sizeof(watch_style));
#endif
}
extern void virfat_flash_get_dirinfo(void *file_buf, u32 *file_num);
int watch_set_init()
{
#if UI_WATCH_RES_ENABLE
u32 i, j;
u32 len;
u32 file_num;
char *fname_buf;
char *suffix = ".sty";
u8 root_path_len = strlen(RES_PATH);
u8 suffix_len = strlen(suffix);
u8 fname_len;
char *fname;
for (i = 0; i < WATCH_ITEMS_LIMIT; i++) {
if (watch_res[i] != NULL) {
free(watch_res[i]);
watch_res[i] = NULL;
}
}
watch_style = 0;
watch_items = 0;
for (i = 0; i < BGP_ITEMS_LIMIT; i++) {
if (watch_bgp[i]) {
free(watch_bgp[i]);
watch_bgp[i] = NULL;
}
}
watch_bgp_items = 0;
virfat_flash_get_dirinfo(NULL, &file_num);
fname_buf = zalloc(file_num * 12);
/* ASSERT((fname_buf != NULL), "fname_buf zalloc faile\n"); */
if (fname_buf == NULL) {
printf("fname_buf zalloc faile %d\n", file_num);
/* while (1); */
return -1;
}
virfat_flash_get_dirinfo(fname_buf, &file_num);
/* printf("fnum %d\n", file_num); */
/* ASSERT((file_num < WATCH_ITEMS_LIMIT), "file num overflow %d\n", file_num); */
/* if (file_num >= WATCH_ITEMS_LIMIT) { */
if (file_num >= BGP_ITEMS_LIMIT) {
printf("file num overflow %d\n", file_num);
/* while (1); */
return -1;
}
for (i = 0; i < file_num; i++) {
fname = &fname_buf[i * 12];
for (j = 0; j < 12; j++) {
/* printf("j %x, %x\n", j, fname[j]); */
if (fname[j] == ' ') {
fname[j] = '\0';
break;
}
}
/* ASSERT((j != 12), "\n\n\n\nfname overflow\n\n\n\n\n"); */
if (j == 12) {
printf("\n\n\n\nfname overflow\n\n\n\n\n");
/* while (1); */
return -1;
}
fname_len = strlen(fname);
ASCII_ToLower(fname, fname_len);
//printf("fname %d, %d, %s\n", j, fname_len, fname);
/* if (strncmp(fname, "watch", strlen("watch")) != 0) { */
/* continue; */
/* } */
if (strncmp(fname, "watch", strlen("watch")) == 0) {
len = root_path_len + fname_len + 1 + fname_len + suffix_len;
watch_res[watch_items] = malloc(len + 1);
/* ASSERT((watch_res[watch_items] != NULL), "\n\nmalloc watch list err\n\n"); */
if (watch_res[watch_items] == NULL) {
printf("\n\nmalloc watch list err\n\n");
/* while (1); */
return -1;
}
strcpy(watch_res[watch_items], RES_PATH);
strcpy(&watch_res[watch_items][root_path_len], fname);
watch_res[watch_items][root_path_len + fname_len] = '/';
strcpy(&watch_res[watch_items][root_path_len + fname_len + 1], fname);
strcpy(&watch_res[watch_items][root_path_len + fname_len + 1 + fname_len], suffix);
watch_res[watch_items][len] = '\0';
printf("watch list : %s, %d, %d\n", watch_res[watch_items], watch_items, len);
watch_items++;
} else if (strncmp(fname, "bgp_w", strlen("bgp_w")) == 0) {
watch_bgp_add(fname);
}
}
free(fname_buf);
if (watch_bgp_related_init() != 0) {
printf("bgp_related_init fail\n");
} else {
printf("bgp_related_init succ\n");
}
if ((sizeof(watch_style) != syscfg_read(VM_WATCH_SELECT, &watch_style, sizeof(watch_style))) || (watch_style >= watch_items)) {
watch_style = 0;
}
/* if (wmem_test_flag == 1) { */
/* watch_bgp_set_related("bgp_w0", 0); */
/* watch_bgp_set_related("bgp_w2", 1); */
/* watch_bgp_set_related("bgp_w1", 2); */
/* watch_bgp_set_related("bgp_w0", 3); */
/* watch_bgp_set_related("bgp_w1", 5); */
/* } */
/* watch_bgp_add("dial0.bin"); */
/* watch_bgp_add("dial1.bin"); */
/* watch_bgp_add("dial2.bin"); */
/* watch_bgp_del("dial1.bin"); */
/* watch_bgp_set_related("dial0.bin", 0); */
/* watch_bgp_set_related("dial2.bin", 1); */
/* watch_bgp_set_related("dial1.bin", 2); */
/* watch_bgp_set_related("dial2.bin", 3); */
/* watch_bgp_set_related("dial1.bin", 4); */
/* watch_bgp_set_related("dial0.bin", 5); */
#endif
return 0;
}
AT_UI_RAM
static void *br23_load_widget_info(void *__head, u8 page)
{
struct ui_file_head head ALIGNED(4);
static union ui_control_info info ALIGNED(4) = {0};
static const int rotate[] = {0, 90, 180, 270};
static int last_page = -1;
int head_len;
int retry = 10;
u32 offset;
u32 _head = ((u32)__head) & 0xffff;
if ((((u32)__head >> 29) & 0x7)) {
if ((((u32)__head >> 29) & 0x7) == 1) {
/* printf("%s \n",watch_res[watch_style]); */
ui_set_sty_path_by_pj_id(1, watch_res[watch_style]);
/* printf(" >>>>>>>>%s %d %x\n",__FUNCTION__,__LINE__,(int)__head >> 29); */
}
ui_file = ui_load_sty_by_pj_id((((u32)__head >> 29) & 0x7));
} else {
ui_file = ui_file1;
}
if (!_head) {
struct ui_style style = {0};
#if UI_WATCH_RES_ENABLE
int load_style = 0;
if (last_page == -1) { //第一次上电未初始化
if (page == 0) { //表盘界面
style.file = watch_res[watch_style];
} else {//其他界面
style.file = RES_PATH"JL/JL.sty";
}
load_style = 1;
} else if ((page == 0) && (last_page == 0)) { // 表盘 -> 表盘
style.file = watch_res[watch_style];
load_style = 1;
} else if ((page == 0) && (last_page > 0)) { //其他 -> 表盘
style.file = watch_res[watch_style];
load_style = 1;
} else if ((page > 0) && (last_page == 0)) {//表盘 -> 其他
style.file = RES_PATH"JL/JL.sty";
load_style = 1;
}
last_page = page;
#if UI_UPGRADE_RES_ENABLE//升级模式加载资源
if (app_get_curr_task() == APP_WATCH_UPDATE_TASK ||
app_get_curr_task() == APP_SMARTBOX_ACTION_TASK) {
ui_set_sty_path_by_pj_id(1, NULL);
style.file = UPGRADE_PATH"upgrade.sty";
load_style = 1;
last_page = -1;//下次能重新加载资源
if (page) {
printf("NOW IS UPGRADE MODE ,CAN NOT SHOW OTHER PAGE...\n");
page = 0;
}
}
#endif
#else
int load_style = 1;
last_page = page;
#endif
if (load_style && platform_api->load_style) {
if (platform_api->load_style(&style)) {
return NULL;
}
load_style = 0;
}
if (!ui_file) {
return NULL;
}
/* last_page = page; */
res_fseek(ui_file, 0, SEEK_SET);
res_fread(ui_file, &head, sizeof(struct ui_file_head));
ui_rotate = rotate[head.rotate];
ui_core_set_rotate(ui_rotate);
switch (head.rotate) {
case 1: /* 旋转90度 */
ui_hori_mirror = true;
ui_vert_mirror = false;
break;
case 3:/* 旋转270度 */
ui_hori_mirror = false;
ui_vert_mirror = true;
break;
default:
ui_hori_mirror = false;
ui_vert_mirror = false;
break;
}
if (page != (u8) - 1) {
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &__this->window_offset, sizeof(__this->window_offset));
}
}
ASSERT((u32)_head <= ui_file_len, ",_head invalid! _head : 0x%x ui_file_len : 0x%x\n", (u32)_head, ui_file_len);
if ((u32)_head > ui_file_len) {
return NULL;
}
if ((u32)__head >= 0x10000) {
page = ((u32)__head >> 22) & 0x7f;
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(__this->window_offset));
} else {
offset = __this->window_offset;
}
res_fseek(ui_file, offset + (u32)_head, SEEK_SET);
if ((u32)_head == 0) {
res_fread(ui_file, &info, sizeof(struct window_info));
} else {
res_fread(ui_file, &info.head, sizeof(struct ui_ctrl_info_head));
head_len = info.head.len - sizeof(struct ui_ctrl_info_head);
if ((head_len > 0) && (head_len <= sizeof(union ui_control_info))) {
res_fread(ui_file, &((u8 *)&info)[sizeof(struct ui_ctrl_info_head)], head_len);
}
}
return &info;
}
AT_UI_RAM
static void *br23_load_css(u8 page, void *_css)
{
u32 rets;
__asm__ volatile("%0 = rets":"=r"(rets));
static struct element_css1 css ALIGNED(4) = {0};
u32 offset;
/* printf(" >>>>>>>>%s %d %x %x\n",__FUNCTION__,__LINE__,((u32)_css) >> 29,rets); */
if ((((u32)_css >> 29) & 0x7)) {
ui_file = ui_load_sty_by_pj_id((((u32)_css >> 29) & 0x7));
} else {
ui_file = ui_file1;
}
/* printf(" >>>>>>>>%s %d file = %x\n",__FUNCTION__,__LINE__,ui_file); */
if ((u32)_css >= 0x10000) {
/* offset = ((u32)_css) >> 16; */
page = ((u32)_css >> 22) & 0x7f;
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(offset));
} else {
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(offset));
/* offset = __this->window_offset; */
}
ASSERT((u32)_css <= ui_file_len, ", _css invalid! _css : 0x%x , ui_file_len : 0x%x\n", _css, ui_file_len);
res_fseek(ui_file, offset/* __this->window_offset */ + ((u32)_css & 0xffff), SEEK_SET);
res_fread(ui_file, &css, sizeof(struct element_css1));
return &css;
}
AT_UI_RAM
static void *br23_load_image_list(u8 page, void *_list)
{
u16 image[32] ALIGNED(4);
static struct ui_image_list_t list ALIGNED(4) = {0};
int retry = 10;
u32 offset;
/* printf(" >>>>>>>>%s %d %x\n",__FUNCTION__,__LINE__,(int)_list >> 29); */
if ((((u32)_list >> 29) & 0x7)) {
ui_file = ui_load_sty_by_pj_id((((u32)_list >> 29) & 0x7));
} else {
ui_file = ui_file1;
}
if ((u32)_list >= 0x10000) {
/* offset = ((u32)_list) >> 16; */
page = ((u32)_list >> 22) & 0x7f;
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(__this->window_offset));
} else {
/* offset = __this->window_offset; */
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(offset));
}
if ((u32)_list == 0) {
return NULL;
}
ASSERT((u32)_list <= ui_file_len, ", _list invalid! _list : 0x%x, ui_file_len : 0x%x\n", (u32)_list, ui_file_len);
do {
memset(&list, 0x00, sizeof(struct ui_image_list));
res_fseek(ui_file, offset/* __this->window_offset */ + ((u32)_list & 0xffff), SEEK_SET);
res_fread(ui_file, &list.num, sizeof(list.num));
if (list.num == 0) {
printf("list.num : %d\n", list.num);
return NULL;
}
if (list.num < 32) {
res_fread(ui_file, image, list.num * sizeof(list.image[0]));
memcpy(list.image, image, list.num * sizeof(list.image[0]));
} else {
printf("list.num = %d\n", list.num);
printf("load_image_list error,retry %d!\n", retry);
if (retry == 0) {
return NULL;
}
}
} while (retry--);
return &list;
}
AT_UI_RAM
static void *br23_load_text_list(u8 page, void *__list)
{
u8 buf[16 * 2] ALIGNED(4);
static struct ui_text_list_t _list ALIGNED(4) = {0};
struct ui_text_list_t *list;
int retry = 10;
int i;
u32 offset;
/* printf(" >>>>>>>>%s %d %x\n",__FUNCTION__,__LINE__,(u32)__list >> 29); */
if ((((u32)__list >> 29) & 0x7)) {
ui_file = ui_load_sty_by_pj_id((((u32)__list >> 29) & 0x7));
} else {
ui_file = ui_file1;
}
if (!ui_file) {
return NULL;
}
if ((u32)__list >= 0x10000) {
/* offset = ((u32)__list) >> 16; */
page = ((u32)__list >> 22) & 0x7f;
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(__this->window_offset));
} else {
/* offset = __this->window_offset; */
res_fseek(ui_file, sizeof(struct ui_file_head) + sizeof(struct window_head)*page, SEEK_SET);
res_fread(ui_file, &offset, sizeof(offset));
}
if ((u32)__list == 0) {
return NULL;
}
ASSERT((u32)__list <= ui_file_len, ", __list invalid! _list : 0x%x, ui_file_len : 0x%x\n", (u32)__list, ui_file_len);
list = &_list;
do {
memset(list, 0x00, sizeof(struct ui_text_list_t));
res_fseek(ui_file, offset/* __this->window_offset */ + ((u32)__list & 0xffff), SEEK_SET);
res_fread(ui_file, &list->num, sizeof(list->num));
if (list->num == 0) {
return NULL;
}
if (list->num <= 16) {
res_fread(ui_file, buf, list->num * 2);
for (i = 0; i < list->num; i++) {
ASSERT(buf[2 * i] < 0x100);
list->str[i] = buf[2 * i];
}
} else {
printf("list->num = %d\n", list->num);
printf("load_text_list error, retry %d!\n", retry);
if (retry == 0) {
return NULL;
}
}
} while (retry--);
return list;
}
static void *br23_load_window(int id)
{
u8 *ui;
int i;
u32 *ptr;
u16 *ptr_table;
struct ui_file_head head ALIGNED(4);
struct window_head window ALIGNED(4);
int len = sizeof(struct ui_file_head);
int retry;
static const int rotate[] = {0, 90, 180, 270};
if (!ui_file) {
printf("ui_file : 0x%x\n", ui_file);
return NULL;
}
ui_platform_ok();
for (retry = 0; retry < set_retry_cnt(); retry++) {
res_fseek(ui_file, 0, SEEK_SET);
res_fread(ui_file, &head, len);
if (id >= head.window_num) {
return NULL;
}
res_fseek(ui_file, sizeof(struct window_head)*id, SEEK_CUR);
res_fread(ui_file, &window, sizeof(struct window_head));
u16 crc = CRC16(&window, (u32) & (((struct window_head *)0)->crc_data));
if (crc == window.crc_head) {
ui_rotate = rotate[head.rotate];
ui_core_set_rotate(ui_rotate);
switch (head.rotate) {
case 1: /* 旋转90度 */
ui_hori_mirror = true;
ui_vert_mirror = false;
break;
case 3:/* 旋转270度 */
ui_hori_mirror = false;
ui_vert_mirror = true;
break;
default:
ui_hori_mirror = false;
ui_vert_mirror = false;
break;
}
goto __read_data;
}
}
return NULL;
__read_data:
ui = (u8 *)__this->api->malloc(window.len);
if (!ui) {
return NULL;
}
for (retry = 0; retry < set_retry_cnt(); retry++) {
res_fseek(ui_file, window.offset, SEEK_SET);
res_fread(ui_file, ui, window.len);
u16 crc = CRC16(ui, window.len);
if (crc == window.crc_data) {
goto __read_table;
}
}
__this->api->free(ui);
return NULL;
__read_table:
ptr_table = (u16 *)__this->api->malloc(window.ptr_table_len);
if (!ptr_table) {
__this->api->free(ui);
return NULL;
}
for (retry = 0; retry < set_retry_cnt(); retry++) {
res_fseek(ui_file, window.ptr_table_offset, SEEK_SET);
res_fread(ui_file, ptr_table, window.ptr_table_len);
u16 crc = CRC16(ptr_table, window.ptr_table_len);
if (crc == window.crc_table) {
u16 *offset = ptr_table;
for (i = 0; i < window.ptr_table_len; i += 2) {
ptr = (u32 *)(ui + *offset++);
if (*ptr != 0) {
*ptr += (u32)ui;
}
}
__this->api->free(ptr_table);
return ui;
}
}
__this->api->free(ui);
__this->api->free(ptr_table);
return NULL;
}
static void br23_unload_window(void *ui)
{
if (ui) {
__this->api->free(ui);
}
}
static int br23_load_style(struct ui_style *style)
{
int err;
int i, j;
int len;
struct vfscan *fs;
char name[64];
char style_name[16];
static char cur_style = 0xff;
if (!style->file && cur_style == 0) {
return 0;
}
if (ui_file1) {
fclose(ui_file1);
ui_file1 = NULL;
}
if (style->file == NULL) {
cur_style = 0;
err = open_resource_file();
if (err) {
return -EINVAL;
}
#if 0
fs = fscan("mnt/spiflash/res", "-t*.sty");
if (!fs) {
printf("open mnt/spiflash/res fail!\n");
return -EFAULT;
}
ui_file1 = fselect(fs, FSEL_FIRST_FILE, 0);
if (!ui_file1) {
fscan_release(fs);
return -ENOENT;
}
len = fget_name(ui_file1, (u8 *)name, 16);
if (len) {
style_name[len - 4] = 0;
memcpy(style_name, name, len - 4);
ui_core_set_style(style_name);
}
fscan_release(fs);
#else
ui_file1 = res_fopen(RES_PATH"JL.sty", "r");
if (!ui_file1) {
return -ENOENT;
}
ui_file_len = res_flen(ui_file1);
len = 6;
strcpy(style_name, "JL.sty");
if (len) {
style_name[len - 4] = 0;
ui_core_set_style(style_name);
}
#endif
} else {
cur_style = 1;
ui_file1 = res_fopen(style->file, "r");
printf("open stylefile %s\n", style->file);
if (!ui_file1) {
return -EINVAL;
}
/* if (!ui_file2) { */
/* ui_file2 = fopen(RES_PATH"sidebar/sidebar.sty", "r"); */
/* } */
ui_file = ui_file1;
ui_file_len = 0xffffffff;//res_flen(ui_file1);
for (i = 0; style->file[i] != '.'; i++) {
name[i] = style->file[i];
}
name[i++] = '.';
name[i++] = 'r';
name[i++] = 'e';
name[i++] = 's';
name[i] = '\0';
open_resfile(name);
printf("open resfile %s\n", name);
name[--i] = 'r';
name[--i] = 't';
name[--i] = 's';
open_str_file(name);
printf("open strfile %s\n", name);
name[i++] = 'a';
name[i++] = 's';
name[i++] = 'i';
font_ascii_init(RES_PATH"font/ascii.res");
printf("open asciifile %s\n", name);
for (i = strlen(style->file) - 5; i >= 0; i--) {
if (style->file[i] == '/') {
break;
}
}
for (i++, j = 0; style->file[i] != '\0'; i++) {
if (style->file[i] == '.') {
name[j] = '\0';
break;
}
name[j++] = style->file[i];
}
ASCII_ToUpper(name, j);
if (!strncmp(name, "WATCH", strlen("WATCH"))) {
strcpy(name, "DIAL");
}
err = ui_core_set_style(name);
if (err) {
printf("style_err: %s\n", name);
}
}
return 0;
__err2:
close_resfile();
__err1:
fclose(ui_file1);
ui_file1 = NULL;
return err;
}
static int br23_open_draw_context(struct draw_context *dc)
{
dc->buf_num = 1;
if (__this->lcd->buffer_malloc) {
u8 *buf;
u32 len;
__this->lcd->buffer_malloc(&buf, &len);
dc->buf0 = buf;
#if UI_USED_DOUBLE_BUFFER
dc->buf1 = &buf[len / 2];
dc->len = len / 2;
#else
dc->buf1 = NULL;
dc->len = len;
#endif
dc->buf = dc->buf0;
/* __this->lcd->buffer_malloc(&dc->buf, &dc->len); */
}
if (__this->lcd->get_screen_info) {
__this->lcd->get_screen_info(&__this->info);
dc->width = __this->info.width;
dc->height = __this->info.height;
dc->col_align = __this->info.col_align;
dc->row_align = __this->info.row_align;
dc->lines = dc->len / dc->width / 2;
if (dc->lines > (dc->height / 10)) {
dc->lines = dc->height / 10;
}
printf("dc->width : %d, dc->lines : %d\n", dc->width, dc->lines);
}
switch (__this->info.color_format) {
case LCD_COLOR_RGB565:
if (dc->data_format != DC_DATA_FORMAT_OSD16) {
ASSERT(0, "The color format of layer don't match the lcd driver,page %d please select OSD16!", dc->page);
}
break;
case LCD_COLOR_MONO:
if (dc->data_format != DC_DATA_FORMAT_MONO) {
ASSERT(0, "The color format of layer don't match the lcd driver,page %d please select OSD1!", dc->page);
}
break;
}
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
dc->fbuf_len = __this->info.width * (3 + 3 * dc->lines) + 0x80;
dc->fbuf = (u8 *)__this->api->malloc(dc->fbuf_len);
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
dc->fbuf_len = __this->info.width * 2;
dc->fbuf = (u8 *)__this->api->malloc(dc->fbuf_len);
}
return 0;
}
static int br23_get_draw_context(struct draw_context *dc)
{
#if UI_USED_DOUBLE_BUFFER
if (dc->buf == dc->buf0) {
dc->buf = dc->buf1;
} else {
dc->buf = dc->buf0;
}
#endif
dc->disp.left = dc->need_draw.left;
dc->disp.width = dc->need_draw.width;
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
int lines = dc->len / dc->need_draw.width / 2;
if ((dc->disp.top == 0) && (dc->disp.height == 0)) {
dc->disp.top = dc->need_draw.top;
dc->disp.height = lines > dc->need_draw.height ? dc->need_draw.height : lines;
} else {
dc->disp.top = dc->disp.top + dc->disp.height;
dc->disp.height = lines > (dc->need_draw.top + dc->need_draw.height - dc->disp.top) ?
(dc->need_draw.top + dc->need_draw.height - dc->disp.top) : lines;
}
dc->disp.height = dc->disp.height / dc->row_align * dc->row_align;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
dc->disp.top = dc->need_draw.top;
dc->disp.height = dc->need_draw.height;
}
return 0;
}
static int br23_put_draw_context(struct draw_context *dc)
{
if (__this->lcd->set_draw_area) {
__this->lcd->set_draw_area(dc->disp.left, dc->disp.left + dc->disp.width - 1,
dc->disp.top, dc->disp.top + dc->disp.height - 1);
}
u8 wait = ((dc->need_draw.top + dc->need_draw.height) == (dc->disp.top + dc->disp.height)) ? 1 : 0;
if (__this->lcd->draw) {
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
__this->lcd->draw(dc->buf, dc->disp.height * dc->disp.width * 2, wait);
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
__this->lcd->draw(dc->buf, __this->info.width * __this->info.height / 8, wait);
}
}
return 0;
}
static int br23_set_draw_context(struct draw_context *dc)
{
return 0;
}
static int br23_close_draw_context(struct draw_context *dc)
{
if (__this->lcd->buffer_free) {
__this->lcd->buffer_free(dc->buf);
}
if (dc->fbuf) {
__this->api->free(dc->fbuf);
dc->fbuf = NULL;
dc->fbuf_len = 0;
}
return 0;
}
static int br23_invert_rect(struct draw_context *dc, u32 acolor)
{
int i;
int len;
int w, h;
int color = acolor & 0xffff;
if (dc->data_format == DC_DATA_FORMAT_MONO) {
color |= BIT(31);
for (h = 0; h < dc->draw.height; h++) {
for (w = 0; w < dc->draw.width; w++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, dc->draw.left + w, dc->draw.top + h, color);
}
}
}
}
return 0;
}
static int br23_fill_rect(struct draw_context *dc, u32 acolor)
{
int i;
int w, h;
u16 color = acolor & 0xffff;
if (!dc->buf) {
return 0;
}
if (dc->data_format == DC_DATA_FORMAT_MONO) {
color = (color == UI_RGB565(BGC_MONO_SET)) ? 0xffff : 0x55aa;
for (h = 0; h < dc->draw.height; h++) {
for (w = 0; w < dc->draw.width; w++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, dc->draw.left + w, dc->draw.top + h, color);
}
}
}
} else {
u16 color16 = (color >> 8) | ((color & 0xff) << 8);
u32 color32 = (color16 << 16) | color16;
h = 0;
u32 *p32 = (u32 *)&dc->buf[(dc->draw.top + h - dc->disp.top) * dc->disp.width * 2 + (dc->draw.left - dc->disp.left) * 2];
u32 *_p32 = p32;
u32 len = dc->draw.width * 2;
if ((u32)p32 % 4) {
u16 *p16 = (u16 *)p32;
*p16++ = color16;
p32 = (u32 *)p16;
len -= 2;
ASSERT((u32)p32 % 4 == 0);
}
u32 count = len / 4;
while (count--) {
*p32++ = color32;
}
count = (len % 4) / 2;
u16 *p16 = (u16 *)p32;
while (count--) {
*p16++ = color16;
}
for (h = 1; h < dc->draw.height; h++) {
u32 *__p32 = (u32 *)&dc->buf[(dc->draw.top + h - dc->disp.top) * dc->disp.width * 2 + (dc->draw.left - dc->disp.left) * 2];
memcpy(__p32, _p32, dc->draw.width * 2);
}
}
return 0;
}
static inline void __draw_vertical_line(struct draw_context *dc, int x, int y, int width, int height, int color, int format)
{
int i, j;
struct rect r = {0};
struct rect disp = {0};
disp.left = x;
disp.top = y;
disp.width = width;
disp.height = height;
if (!get_rect_cover(&dc->draw, &disp, &r)) {
return;
}
switch (format) {
case DC_DATA_FORMAT_OSD16:
for (i = 0; i < r.width; i++) {
for (j = 0; j < r.height; j++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, r.left + i, r.top + j, color);
}
}
}
break;
case DC_DATA_FORMAT_MONO:
for (i = 0; i < r.width; i++) {
for (j = 0; j < r.height; j++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, r.left + i, r.top + j, color);
}
}
}
break;
}
}
static inline void __draw_line(struct draw_context *dc, int x, int y, int width, int height, int color, int format)
{
int i, j;
struct rect r = {0};
struct rect disp = {0};
disp.left = x;
disp.top = y;
disp.width = width;
disp.height = height;
if (!get_rect_cover(&dc->draw, &disp, &r)) {
return;
}
switch (format) {
case DC_DATA_FORMAT_OSD16:
for (i = 0; i < r.height; i++) {
for (j = 0; j < r.width; j++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, r.left + j, r.top + i, color);
}
}
}
break;
case DC_DATA_FORMAT_MONO:
for (i = 0; i < r.height; i++) {
for (j = 0; j < r.width; j++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, r.left + j, r.top + i, color);
}
}
}
break;
}
}
static int br23_draw_rect(struct draw_context *dc, struct css_border *border)
{
int err;
int offset;
int color = border->color & 0xffff;
/* draw_rect_range_check(&dc->draw, map); */
/* draw_rect_range_check(&dc->rect, map); */
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
color = border->color & 0xffff;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
color = (color != UI_RGB565(RECT_MONO_CLR)) ? (color ? color : 0xffff) : 0x55aa;
}
if (border->left) {
if (dc->rect.left >= dc->draw.left &&
dc->rect.left <= rect_right(&dc->draw)) {
__draw_vertical_line(dc, dc->draw.left, dc->draw.top,
border->left, dc->draw.height, color, dc->data_format);
}
}
if (border->right) {
if (rect_right(&dc->rect) >= dc->draw.left &&
rect_right(&dc->rect) <= rect_right(&dc->draw)) {
__draw_vertical_line(dc, dc->draw.left + dc->draw.width - border->right, dc->draw.top,
border->right, dc->draw.height, color, dc->data_format);
}
}
if (border->top) {
if (dc->rect.top >= dc->draw.top &&
dc->rect.top <= rect_bottom(&dc->draw)) {
__draw_line(dc, dc->draw.left, dc->draw.top,
dc->draw.width, border->top, color, dc->data_format);
}
}
if (border->bottom) {
if (rect_bottom(&dc->rect) >= dc->draw.top &&
rect_bottom(&dc->rect) <= rect_bottom(&dc->draw)) {
__draw_line(dc, dc->draw.left, dc->draw.top + dc->draw.height - border->bottom,
dc->draw.width, border->bottom, color, dc->data_format);
}
}
return 0;
}
__attribute__((always_inline_when_const_args))
AT_UI_RAM
static u16 get_mixed_pixel(u16 backcolor, u16 forecolor, u8 alpha)
{
u16 mixed_color;
u8 r0, g0, b0;
u8 r1, g1, b1;
u8 r2, g2, b2;
if (alpha == 255) {
return (forecolor >> 8) | (forecolor & 0xff) << 8;
} else if (alpha == 0) {
return (backcolor >> 8) | (backcolor & 0xff) << 8;
}
r0 = ((backcolor >> 11) & 0x1f) << 3;
g0 = ((backcolor >> 5) & 0x3f) << 2;
b0 = ((backcolor >> 0) & 0x1f) << 3;
r1 = ((forecolor >> 11) & 0x1f) << 3;
g1 = ((forecolor >> 5) & 0x3f) << 2;
b1 = ((forecolor >> 0) & 0x1f) << 3;
r2 = (alpha * r1 + (255 - alpha) * r0) / 255;
g2 = (alpha * g1 + (255 - alpha) * g0) / 255;
b2 = (alpha * b1 + (255 - alpha) * b0) / 255;
mixed_color = ((r2 >> 3) << 11) | ((g2 >> 2) << 5) | (b2 >> 3);
return (mixed_color >> 8) | (mixed_color & 0xff) << 8;
}
static int br23_read_image_info(struct draw_context *dc, u32 id, u8 page, struct ui_image_attrs *attrs)
{
struct image_file file;
if (((u16) - 1 == id) || ((u32) - 1 == id)) {
return -1;
}
select_resfile(dc->prj);
int err = open_image_by_id(NULL, &file, id, dc->page);
if (err) {
return -EFAULT;
}
attrs->width = file.width;
attrs->height = file.height;
return 0;
}
AT_UI_RAM
int line_update(u8 *mask, u16 y, u16 width)
{
int i;
if (!mask) {
return true;
}
for (i = 0; i < (width + 7) / 8; i++) {
if (mask[y * ((width + 7) / 8) + i]) {
return true;
}
}
return false;
}
/* AT_UI_RAM */
void select_resfile(u8 index);
void select_strfile(u8 index);
static int br23_draw_image(struct draw_context *dc, u32 src, u8 quadrant, u8 *mask)
{
u8 *pixelbuf;
u8 *temp_pixelbuf;
u8 *alphabuf;
u8 *temp_alphabuf;
struct rect draw_r;
struct rect r = {0};
struct rect disp = {0};
struct image_file file;
int h, hh, w;
int buf_offset;
int id;
int page;
FILE *fp;
if (dc->preview.file) {
fp = dc->preview.file;
id = dc->preview.id;
page = dc->preview.page;
} else {
fp = NULL;
id = src;
page = dc->page;
}
if (((u16) - 1 == id) || ((u32) - 1 == id)) {
return -1;
}
draw_r.left = dc->draw.left;
draw_r.top = dc->draw.top;
draw_r.width = dc->draw.width;
draw_r.height = dc->draw.height;
/* UI_PRINTF("image draw %d, %d, %d, %d\n", dc->draw.left, dc->draw.top, dc->draw.width, dc->draw.height); */
/* UI_PRINTF("image rect %d, %d, %d, %d\n", dc->rect.left, dc->rect.top, dc->rect.width, dc->rect.height); */
select_resfile(dc->prj);
if (dc->draw_img.en) {
id = dc->draw_img.id;
page = dc->draw_img.page;
}
int err = open_image_by_id(fp, &file, id, page);
if (err) {
return -EFAULT;
}
int x = dc->rect.left;
int y = dc->rect.top;
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - file.width / 2);
y += (dc->rect.height / 2 - file.height / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += dc->rect.width - file.width;
}
int temp_pixelbuf_len;
int temp_alphabuf_len;
int align;
if (dc->draw_img.en) {
disp.left = dc->draw_img.x;
disp.top = dc->draw_img.y;
} else {
disp.left = x;
disp.top = y;
}
disp.width = file.width;
disp.height = file.height;
if (dc->data_format == DC_DATA_FORMAT_MONO) {
pixelbuf = dc->fbuf;
if (get_rect_cover(&draw_r, &disp, &r)) {
int _offset = -1;
for (h = 0; h < r.height; h++) {
if (file.compress == 0) {
int offset = (r.top + h - disp.top) / 8 * file.width + (r.left - disp.left);
if (_offset != offset) {
if (br23_read_image_data(fp, &file, pixelbuf, r.width, offset) != r.width) {
return -EFAULT;
}
_offset = offset;
}
} else {
ASSERT(0, "the compress mode not support!");
}
for (w = 0; w < r.width; w++) {
u8 color = (pixelbuf[w] & BIT((r.top + h - disp.top) % 8)) ? 1 : 0;
if (color) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, r.left + w, r.top + h, color);
}
}
}
}
}
} else if (dc->data_format == DC_DATA_FORMAT_OSD16) {
if (get_rect_cover(&draw_r, &disp, &r)) {
u32 alpha_addr = 0;
br23_read_image_data(fp, &file, &alpha_addr, sizeof(alpha_addr), 0);
if (alpha_addr) {
temp_pixelbuf_len = dc->width * 2 * dc->lines + 0x40 - 8;
temp_alphabuf_len = dc->width * dc->lines + 0x40 - 8;
buf_offset = 0;
pixelbuf = &dc->fbuf[buf_offset];//2 bytes * line
buf_offset += dc->width * 2;
buf_offset = (buf_offset + 3) / 4 * 4;
alphabuf = &dc->fbuf[buf_offset];//1 bytes * line
buf_offset += dc->width;
buf_offset = (buf_offset + 3) / 4 * 4;
temp_pixelbuf = &dc->fbuf[buf_offset];
buf_offset += temp_pixelbuf_len;
buf_offset = (buf_offset + 3) / 4 * 4;
temp_alphabuf = &dc->fbuf[buf_offset];
} else {
/* temp_pixelbuf_len = dc->width * 3 * dc->lines + 0x80; */
temp_pixelbuf_len = dc->fbuf_len - dc->width * 2;
buf_offset = 0;
pixelbuf = &dc->fbuf[buf_offset];//2 bytes * line
buf_offset += dc->width * 2;
buf_offset = (buf_offset + 3) / 4 * 4;
temp_pixelbuf = &dc->fbuf[buf_offset];
}
for (h = 0; h < r.height;) {
int rh = r.top + h - disp.top;
int rw = r.left - disp.left;
int vh = rh;
int vw = rw;
if (quadrant == 0) {
;
} else if (quadrant == 1) {
vh = file.height - (r.top - disp.top + r.height - h);
} else if (quadrant == 2) {
vh = file.height - (r.top - disp.top + r.height - h);
vw = file.width - rw - r.width;
} else {
vw = file.width - rw - r.width;
}
ASSERT(vw >= 0);
ASSERT(vh >= 0);
struct rle_line *line;
struct rle_line *alpha_line;
u8 *ptemp;
u8 *alpha_ptemp;
int lines;
if (file.compress == 0) {
int remain = (r.height - h) > (file.height - vh) ? (file.height - vh) : (r.height - h);
int offset = 4 + vh * file.width * 2 + vw * 2;
br23_read_image_data(fp, &file, &alpha_addr, sizeof(alpha_addr), 0);
if (!alpha_addr) {
lines = dc->fbuf_len / file.width / 2;
} else {
lines = dc->fbuf_len / file.width / 3;
}
lines = (lines > remain) ? remain : lines;
pixelbuf = dc->fbuf;
alphabuf = &dc->fbuf[(lines * file.width * 2 + 3) / 4 * 4];
int remain_bytes = 4 + file.width * 2 * file.height - offset;
int read_bytes = remain_bytes > (file.width * 2 * lines) ? file.width * 2 * lines : remain_bytes;
if (br23_read_image_data(fp, &file, pixelbuf, read_bytes, offset) != read_bytes) {
return -EFAULT;
}
if (alpha_addr) {
offset = alpha_addr + vh * file.width + vw;
int remain_bytes = alpha_addr + file.width * file.height - offset;
int read_bytes = remain_bytes > (file.width * lines) ? file.width * lines : remain_bytes;
if (br23_read_image_data(fp, &file, alphabuf, read_bytes, offset) != read_bytes) {
return -EFAULT;
}
}
} else if (file.compress == 1) {
int remain = (r.height - h) > (file.height - vh) ? (file.height - vh) : (r.height - h);
int headlen = sizeof(struct rle_header) + (remain * 2 + 3) / 4 * 4;
line = (struct rle_line *)temp_pixelbuf;
ptemp = &temp_pixelbuf[headlen];
memset(line, 0x00, sizeof(struct rle_line));
br23_read_image_data(fp, &file, ptemp, sizeof(struct rle_header)*remain, 4 + vh * sizeof(struct rle_header));
int i;
struct rle_header *rle = (struct rle_header *)ptemp;
int total_len = 0;
for (i = 0; i < remain; i++) {
if (i == 0) {
line->addr = rle[i].addr;
line->len[i] = rle[i].len;
} else {
line->len[i] = rle[i].len;
}
if ((total_len + rle[i].len) > (temp_pixelbuf_len - headlen)) {
break;
}
total_len += rle[i].len;
line->num ++;
}
br23_read_image_data(fp, &file, ptemp, total_len, 4 + line->addr);
if (alpha_addr) {
int headlen = sizeof(struct rle_header) + (line->num * 2 + 3) / 4 * 4;
alpha_ptemp = &temp_alphabuf[headlen];
br23_read_image_data(fp, &file, alpha_ptemp, sizeof(struct rle_header)*line->num, alpha_addr + vh * sizeof(struct rle_header));
struct rle_header *rle = (struct rle_header *)alpha_ptemp;
alpha_line = (struct rle_line *)temp_alphabuf;
memset(alpha_line, 0x00, sizeof(struct rle_line));
int total_len = 0;
for (i = 0; i < line->num; i++) {
if (i == 0) {
alpha_line->addr = rle[i].addr;
alpha_line->len[i] = rle[i].len;
} else {
alpha_line->len[i] = rle[i].len;
}
if ((total_len + rle[i].len) > (temp_alphabuf_len - headlen)) {
break;
}
total_len += rle[i].len;
alpha_line->num ++;
}
br23_read_image_data(fp, &file, alpha_ptemp, total_len, alpha_addr + alpha_line->addr);
}
} else {
ASSERT(0, "the compress mode not support!");
}
u8 *p0 = ptemp;
u8 *p1 = alpha_ptemp;
int line_num;
if (file.compress == 0) {
line_num = lines;
} else {
if (alpha_addr) {
line_num = (line->num > alpha_line->num) ? alpha_line->num : line->num;
} else {
line_num = line->num;
}
}
int hs;
int he;
int hstep;
he = h + line_num;
if ((quadrant == 1) || (quadrant == 2)) {
hs = r.height - h - 1;
hstep = -1;
} else {
hs = h;
hstep = 1;
}
for (hh = 0, h = hs; hh < line_num; hh++, h += hstep) {
if (file.compress == 1) {
if (line_update(mask, r.top + h - dc->disp.top, dc->disp.width)) {
Rle_Decode(p0, line->len[hh], pixelbuf, file.width * 2, vw * 2, r.width * 2, 2);
p0 += line->len[hh];
if (alpha_addr) {
Rle_Decode(p1, alpha_line->len[hh], alphabuf, file.width, vw, r.width, 1);
p1 += alpha_line->len[hh];
}
} else {
p0 += line->len[hh];
p1 += alpha_line->len[hh];
continue;
}
}
u16 *pdisp = (u16 *)dc->buf;
u16 *pixelbuf16 = (u16 *)pixelbuf;
if (!alpha_addr) {
u16 x0 = r.left;
u16 y0 = r.top + h;
int offset = (y0 - dc->disp.top) * dc->disp.width + (x0 - dc->disp.left);
/* if ((offset * 2 + 1) < dc->len) { */
/* pdisp[offset] = pixel; */
/* } */
memcpy(&pdisp[offset], pixelbuf16, r.width * 2);
if (file.compress == 0) {
pixelbuf += file.width * 2;
}
continue;
}
for (w = 0; w < r.width; w++) {
u16 color, pixel;
u8 alpha = alpha_addr ? alphabuf[w] : 255;
pixel = color = pixelbuf16[w];
if (alpha) {
if (platform_api->draw_point) {
int vww = w;
if ((quadrant == 2) || (quadrant == 3)) {
vww = r.width - w - 1;
}
u16 x0 = r.left + vww;
u16 y0 = r.top + h;
if (alpha < 255) {
u16 backcolor = platform_api->read_point(dc, x0, y0);
pixel = get_mixed_pixel((backcolor >> 8) | (backcolor & 0xff) << 8, (color >> 8) | (color & 0xff) << 8, alpha);
}
if (mask) {
int yy = y0 - dc->disp.top;
int xx = x0 - dc->disp.left;
if (yy >= dc->disp.height) {
continue;
}
if (xx >= dc->disp.width) {
continue;
}
if (mask[yy * ((dc->disp.width + 7) / 8) + xx / 8] & BIT(xx % 8)) {
int offset = (y0 - dc->disp.top) * dc->disp.width + (x0 - dc->disp.left);
if ((offset * 2 + 1) < dc->len) {
pdisp[offset] = pixel;
}
}
} else {
int offset = (y0 - dc->disp.top) * dc->disp.width + (x0 - dc->disp.left);
if ((offset * 2 + 1) < dc->len) {
pdisp[offset] = pixel;
}
}
}
}
}
if (file.compress == 0) {
pixelbuf += file.width * 2;
alphabuf += file.width;
}
}
h = he;
}
}
}
return 0;
}
int get_multi_string_width(struct draw_context *dc, u8 *str, int *str_width, int *str_height)
{
struct image_file file;
u8 *p = str;
int width = 0;
while (*p != 0) {
select_strfile(dc->prj);
if (open_string_pic(&file, *p)) {
return -EINVAL;
}
width += file.width;
p++;
}
*str_width = width;
*str_height = file.height;
return 0;
}
struct font_info *text_font_init(u8 init)
{
static struct font_info *info = NULL;
static int language = 0;
if (init) {
if (!info || (language != ui_language_get())) {
language = ui_language_get();
if (info) {
font_close(info);
}
info = font_open(NULL, language);
ASSERT(info, "font_open fail!");
}
} else {
if (info) {
font_close(info);
info = NULL;
}
}
return info;
}
static int br23_show_text(struct draw_context *dc, struct ui_text_attrs *text)
{
struct rect draw_r;
struct rect r = {0};
struct rect disp = {0};
struct image_file file;
/* 控件从绝对x,y 转成相对图层的x,y */
int x = dc->rect.left;
int y = dc->rect.top;
/* 绘制区域从绝对x,y 转成相对图层的x,y */
draw_r.left = dc->draw.left;
draw_r.top = dc->draw.top;
draw_r.width = dc->draw.width;
draw_r.height = dc->draw.height;
if (text->format && !strcmp(text->format, "text")) {
struct font_info *info = text_font_init(true);
if (info && (FT_ERROR_NONE == (info->sta & (~(FT_ERROR_NOTABFILE | FT_ERROR_NOPIXFILE))))) {
info->disp.map = 0;
info->disp.rect = &draw_r;
info->disp.format = dc->data_format;
if ((dc->data_format == DC_DATA_FORMAT_MONO) && (text->color == UI_RGB565(TEXT_MONO_INV))) {
if (__this->api->fill_rect) {
__this->api->fill_rect(dc, UI_RGB565(BGC_MONO_SET));
}
}
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
info->disp.color = text->color;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
if (text->color == UI_RGB565(TEXT_MONO_INV)) {
info->disp.color = 0x55aa;//清显示
} else {
info->disp.color = (text->color != UI_RGB565(TEXT_MONO_CLR)) ? (text->color ? text->color : 0xffff) : 0x55aa;
}
}
info->dc = dc;
info->text_width = draw_r.width;
info->text_height = draw_r.height;
info->flags = text->flags;
/* info->offset = text->offset; */
int roll = 0;//需要滚动
int multi_line = 0;
/* FONT_SHOW_MULTI_LINE */
if (text->encode == FONT_ENCODE_ANSI) {
int width = font_text_width(info, (u8 *)text->str, text->strlen);
int height;
if (info->ascpixel.size) {
height = info->ascpixel.size;
} else if (info->pixel.size) {
height = info->pixel.size;
} else {
ASSERT(0, "can't get the height of font.");
}
if (width > dc->rect.width) {
width = dc->rect.width;
roll = 1;
multi_line = 1;
}
if (text->flags & FONT_SHOW_MULTI_LINE) {
height += multi_line * height;
}
if (height > dc->rect.height) {
height = dc->rect.height;
}
y += (dc->rect.height / 2 - height / 2);
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - width / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - width);
}
if (dc->draw_img.en) {//指定坐标刷新
x = dc->draw_img.x;
y = dc->draw_img.y;
}
info->x = x;
info->y = y;
int len = font_textout(info, (u8 *)(text->str + roll * text->offset * 2), text->strlen - roll * text->offset * 2, x, y);
ASSERT(len <= 255);
text->displen = len;
} else if (text->encode == FONT_ENCODE_UNICODE) {
if (FT_ERROR_NONE == (info->sta & ~(FT_ERROR_NOTABFILE | FT_ERROR_NOPIXFILE))) {
if (text->endian == FONT_ENDIAN_BIG) {
info->bigendian = true;
} else {
info->bigendian = false;
}
int width = font_textw_width(info, (u8 *)text->str, text->strlen);
int height;
if (info->ascpixel.size) {
height = info->ascpixel.size;
} else if (info->pixel.size) {
height = info->pixel.size;
} else {
ASSERT(0, "can't get the height of font.");
}
if (width > dc->rect.width) {
width = dc->rect.width;
roll = 1;
multi_line = 1;
}
if (text->flags & FONT_SHOW_MULTI_LINE) {
height += multi_line * height;
}
if (height > dc->rect.height) {
height = dc->rect.height;
}
y += (dc->rect.height / 2 - height / 2);
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - width / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - width);
}
if (dc->draw_img.en) {//指定坐标刷新
x = dc->draw_img.x;
y = dc->draw_img.y;
}
info->x = x;
info->y = y;
int len = font_textout_unicode(info, (u8 *)(text->str + roll * text->offset * 2), text->strlen - roll * text->offset * 2, x, y);
ASSERT(len <= 255);
text->displen = len;
}
} else {
int width = font_textu_width(info, (u8 *)text->str, text->strlen);
int height;
if (info->ascpixel.size) {
height = info->ascpixel.size;
} else if (info->pixel.size) {
height = info->pixel.size;
} else {
ASSERT(0, "can't get the height of font.");
}
if (width > dc->rect.width) {
width = dc->rect.width;
}
if (height > dc->rect.height) {
height = dc->rect.height;
}
y += (dc->rect.height / 2 - height / 2);
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - width / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - width);
}
if (dc->draw_img.en) {//指定坐标刷新
x = dc->draw_img.x;
y = dc->draw_img.y;
}
info->x = x;
info->y = y;
int len = font_textout_utf8(info, (u8 *)text->str, text->strlen, x, y);
ASSERT(len <= 255);
text->displen = len;
}
}
} else if (text->format && !strcmp(text->format, "ascii")) {
char *str;
u32 w_sum;
if (!text->str) {
return 0;
}
if ((u8)text->str[0] == 0xff) {
return 0;
}
if (dc->align == UI_ALIGN_CENTER) {
w_sum = font_ascii_width_check(text->str);
x += (dc->rect.width / 2 - w_sum / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
w_sum = font_ascii_width_check(text->str);
x += (dc->rect.width - w_sum);
}
if (dc->draw_img.en) {//指定坐标刷新
x = dc->draw_img.x;
y = dc->draw_img.y;
}
if ((dc->data_format == DC_DATA_FORMAT_MONO) && (text->color == UI_RGB565(TEXT_MONO_INV))) {
if (__this->api->fill_rect) {
__this->api->fill_rect(dc, UI_RGB565(BGC_MONO_SET));
}
}
str = text->str;
while (*str) {
u8 *pixbuf = dc->fbuf;
int width;
int height;
int color;
font_ascii_get_pix(*str, pixbuf, dc->fbuf_len, &height, &width);
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
color = text->color;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
if (text->color == UI_RGB565(TEXT_MONO_INV)) {
color = 0x55aa;//清显示
} else {
color = (text->color != UI_RGB565(TEXT_MONO_CLR)) ? (text->color ? text->color : 0xffff) : 0x55aa;
}
}
__font_pix_copy(dc, dc->data_format, 0, pixbuf, &draw_r, x, y, height, width, color);
x += width;
str++;
}
} else if (text->format && !strcmp(text->format, "strpic")) {
u16 id = (u8)text->str[0];
u8 *pixbuf;
int w;
int h;
if (id == 0xffff) {
return 0;
}
select_strfile(dc->prj);
if (open_string_pic(&file, id)) {
return 0;
}
y += (dc->rect.height / 2 - file.height / 2);
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - file.width / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - file.width);
}
pixbuf = dc->fbuf;
if (!pixbuf) {
return -ENOMEM;
}
if (dc->draw_img.en) {
x = dc->draw_img.x;
y = dc->draw_img.y;
}
disp.left = x;
disp.top = y;
disp.width = file.width;
disp.height = file.height;
if (get_rect_cover(&draw_r, &disp, &r)) {
if ((dc->data_format == DC_DATA_FORMAT_MONO) && (text->color == UI_RGB565(TEXT_MONO_INV))) {
if (__this->api->fill_rect) {
__this->api->fill_rect(dc, UI_RGB565(BGC_MONO_SET));
}
}
for (h = 0; h < file.height; h += 8) {
if (file.compress == 0) {
int offset = (h / 8) * file.width;
if (br23_read_str_data(&file, pixbuf, file.width, offset) != file.width) {
return -EFAULT;
}
} else {
ASSERT(0, "the compress mode not support!");
}
int color;
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
color = text->color;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
if (text->color == UI_RGB565(TEXT_MONO_INV)) {
color = 0x55aa;//清显示
} else {
color = (text->color != UI_RGB565(TEXT_MONO_CLR)) ? (text->color ? text->color : 0xffff) : 0x55aa;
}
}
__font_pix_copy(dc, dc->data_format, 0, pixbuf, &r, x, y + h / 8 * 8, 8, file.width, color);
}
}
} else if (text->format && !strcmp(text->format, "mulstr")) {
u16 id = (u8)text->str[0];
u8 *pixbuf;
int w;
int h;
u8 *p = text->str;
select_strfile(dc->prj);
if (get_multi_string_width(dc, text->str, &w, &h)) {
return -EINVAL;
}
y += (dc->rect.height / 2 - h / 2);
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - w / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - w);
}
while (*p != 0) {
id = *p;
if (id == 0xffff) {
return 0;
}
select_strfile(dc->prj);
if (open_string_pic(&file, id)) {
return 0;
}
pixbuf = dc->fbuf;
if (!pixbuf) {
return -ENOMEM;
}
disp.left = x;
disp.top = y;
disp.width = file.width;
disp.height = file.height;
if (get_rect_cover(&draw_r, &disp, &r)) {
if ((dc->data_format == DC_DATA_FORMAT_MONO) && (text->color == UI_RGB565(TEXT_MONO_INV))) {
if (__this->api->fill_rect) {
__this->api->fill_rect(dc, UI_RGB565(BGC_MONO_SET));
}
}
for (h = 0; h < file.height; h += 8) {
if (file.compress == 0) {
int offset = (h / 8) * file.width;
if (br23_read_str_data(&file, pixbuf, file.width, offset) != file.width) {
return -EFAULT;
}
} else {
ASSERT(0, "the compress mode not support!");
}
int color;
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
color = text->color;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
if (text->color == UI_RGB565(TEXT_MONO_INV)) {
color = 0x55aa;//清显示
} else {
color = (text->color != UI_RGB565(TEXT_MONO_CLR)) ? (text->color ? text->color : 0xffff) : 0x55aa;
}
}
__font_pix_copy(dc, dc->data_format, 0, pixbuf, &r, x, y + h / 8 * 8, 8, file.width, color);
}
}
x += file.width;
p++;
}
} else if (text->format && !strcmp(text->format, "image")) {
u8 *pixelbuf;
u8 *temp_pixelbuf;
u8 *alphabuf;
u8 *temp_alphabuf;
u16 cnt = 0;
u16 id = ((u8)text->str[1] << 8) | (u8)text->str[0];
u32 w, h;
int ww, hh;
if (image_str_size_check(dc, dc->page, text->str, &ww, &hh) != 0) {
return -EFAULT;
}
if (dc->align == UI_ALIGN_CENTER) {
x += (dc->rect.width / 2 - ww / 2);
} else if (dc->align == UI_ALIGN_RIGHT) {
x += (dc->rect.width - ww);
}
y += (dc->rect.height / 2 - hh / 2);
while ((id != 0x00ff) && (id != 0xffff)) {
select_resfile(dc->prj);
if (open_image_by_id(NULL, &file, id, dc->page) != 0) {
return -EFAULT;
}
disp.left = x;
disp.top = y;
disp.width = file.width;
disp.height = file.height;
if (dc->data_format == DC_DATA_FORMAT_MONO) {
pixelbuf = dc->fbuf;
if (get_rect_cover(&draw_r, &disp, &r)) {
int _offset = -1;
for (h = 0; h < r.height; h++) {
if (file.compress == 0) {
int offset = (r.top + h - disp.top) / 8 * file.width + (r.left - disp.left);
if (_offset != offset) {
if (br23_read_image_data(NULL, &file, pixelbuf, r.width, offset) != r.width) {
return -EFAULT;
}
_offset = offset;
}
} else {
ASSERT(0, "the compress mode not support!");
}
for (w = 0; w < r.width; w++) {
u8 color = (pixelbuf[w] & BIT((r.top + h - disp.top) % 8)) ? 1 : 0;
if (color) {
if (platform_api->draw_point) {
u16 text_color;
if (text->color != 0xffffff) {
text_color = (text->color != UI_RGB565(TEXT_MONO_CLR)) ? (text->color ? text->color : 0xffff) : 0x55aa;
} else {
text_color = color;
}
platform_api->draw_point(dc, r.left + w, r.top + h, text_color);
}
}
}
}
}
} else if (dc->data_format == DC_DATA_FORMAT_OSD16) {
int temp_pixelbuf_len = dc->width * 2 * dc->lines + 0x40 - 8;
int temp_alphabuf_len = dc->width * dc->lines + 0x40 - 8;
int buf_offset;
buf_offset = 0;
pixelbuf = &dc->fbuf[buf_offset];//2 bytes * line
buf_offset += dc->width * 2;
buf_offset = (buf_offset + 3) / 4 * 4;
alphabuf = &dc->fbuf[buf_offset];//1 bytes * line
buf_offset += dc->width;
buf_offset = (buf_offset + 3) / 4 * 4;
temp_pixelbuf = &dc->fbuf[buf_offset];
buf_offset += temp_pixelbuf_len;
buf_offset = (buf_offset + 3) / 4 * 4;
temp_alphabuf = &dc->fbuf[buf_offset];
u32 alpha_addr = 0;
if (get_rect_cover(&draw_r, &disp, &r)) {
for (h = 0; h < r.height;) {
int vh = r.top + h - disp.top;
int vw = r.left - disp.left;
struct rle_line *line;
struct rle_line *alpha_line;
u8 *ptemp;
u8 *alpha_ptemp;
if (file.compress == 0) {
int offset = 4 + vh * file.width * 2 + vw * 2;
if (br23_read_image_data(NULL, &file, pixelbuf, r.width * 2, offset) != r.width * 2) {
return -EFAULT;
}
br23_read_image_data(NULL, &file, &alpha_addr, sizeof(alpha_addr), 0);
if (alpha_addr) {
offset = alpha_addr + vh * file.width + vw;
br23_read_image_data(NULL, &file, alphabuf, r.width, offset);
}
} else if (file.compress == 1) {
int remain = (r.height - h) > (file.height - vh) ? (file.height - vh) : (r.height - h);
int headlen = sizeof(struct rle_header) + (remain * 2 + 3) / 4 * 4;
line = (struct rle_line *)temp_pixelbuf;
ptemp = &temp_pixelbuf[headlen];
memset(line, 0x00, sizeof(struct rle_line));
int rle_header_len = sizeof(struct rle_header) * remain;
br23_read_image_data(NULL, &file, ptemp, rle_header_len, 4 + vh * sizeof(struct rle_header));
int i;
struct rle_header *rle = (struct rle_header *)ptemp;
int total_len = 0;
for (i = 0; i < remain; i++) {
if (i == 0) {
line->addr = rle[i].addr;
line->len[i] = rle[i].len;
} else {
line->len[i] = rle[i].len;
}
if ((total_len + rle[i].len) > (temp_pixelbuf_len - headlen)) {
break;
}
total_len += rle[i].len;
line->num ++;
}
br23_read_image_data(NULL, &file, ptemp, total_len, 4 + line->addr);
br23_read_image_data(NULL, &file, &alpha_addr, sizeof(alpha_addr), 0);
if (alpha_addr) {
int headlen = sizeof(struct rle_header) + (line->num * 2 + 3) / 4 * 4;
alpha_ptemp = &temp_alphabuf[headlen];
br23_read_image_data(NULL, &file, alpha_ptemp, sizeof(struct rle_header)*line->num, alpha_addr + vh * sizeof(struct rle_header));
struct rle_header *rle = (struct rle_header *)alpha_ptemp;
alpha_line = (struct rle_line *)temp_alphabuf;
memset(alpha_line, 0x00, sizeof(struct rle_line));
int total_len = 0;
for (i = 0; i < line->num; i++) {
if (i == 0) {
alpha_line->addr = rle[i].addr;
alpha_line->len[i] = rle[i].len;
} else {
alpha_line->len[i] = rle[i].len;
}
if ((total_len + rle[i].len) > (temp_alphabuf_len - headlen)) {
break;
}
total_len += rle[i].len;
alpha_line->num ++;
}
br23_read_image_data(NULL, &file, alpha_ptemp, total_len, alpha_addr + alpha_line->addr);
}
} else {
ASSERT(0, "the compress mode not support!");
}
u8 *p0 = ptemp;
u8 *p1 = alpha_ptemp;
int line_num;
if (file.compress == 0) {
line_num = 1;
} else {
line_num = (line->num > alpha_line->num) ? alpha_line->num : line->num;
}
for (hh = 0; hh < line_num; hh++, h++) {
if (file.compress == 1) {
Rle_Decode(p0, line->len[hh], pixelbuf, file.width * 2, vw * 2, r.width * 2, 2);
p0 += line->len[hh];
Rle_Decode(p1, alpha_line->len[hh], alphabuf, file.width, vw, r.width, 1);
p1 += alpha_line->len[hh];
}
u16 *pdisp = (u16 *)dc->buf;
u16 *pixelbuf16 = (u16 *)pixelbuf;
for (w = 0; w < r.width; w++) {
u16 color, pixel;
u8 alpha = alpha_addr ? alphabuf[w] : 255;
pixel = color = pixelbuf16[w];
if (alpha) {
if (platform_api->draw_point) {
int vww = w;
u16 x0 = r.left + vww;
u16 y0 = r.top + h;
if (alpha < 255) {
u16 backcolor = platform_api->read_point(dc, x0, y0);
pixel = get_mixed_pixel((backcolor >> 8) | (backcolor & 0xff) << 8, (color >> 8) | (color & 0xff) << 8, alpha);
}
int offset = (y0 - dc->disp.top) * dc->disp.width + (x0 - dc->disp.left);
if ((offset * 2 + 1) < dc->len) {
pdisp[offset] = pixel;
}
}
}
}
}
}
}
}
x += file.width;
cnt += 2;
id = ((u8)text->str[cnt + 1] << 8) | (u8)text->str[cnt];
}
}
return 0;
}
#include "ui/ui_circle.h"
void ui_draw_circle(struct draw_context *dc, int center_x, int center_y,
int radius_small, int radius_big, int angle_begin,
int angle_end, int color, int percent)
{
struct circle_info info;
info.center_x = center_x;
info.center_y = center_y;
info.radius_big = radius_big;
info.radius_small = radius_small;
info.angle_begin = angle_begin;
info.angle_end = angle_end;
info.left = dc->draw.left;
info.top = dc->draw.top;
info.width = dc->draw.width;
info.height = dc->draw.height;
info.x = 0;
info.y = 0;
info.disp_x = dc->disp.left;
info.disp_y = dc->disp.top;
info.color = color;
info.bitmap_width = dc->disp.width;
info.bitmap_height = dc->disp.height;
info.bitmap_pitch = dc->disp.width * 2;
info.bitmap = dc->buf;
info.bitmap_size = dc->len;
info.bitmap_depth = 16;
draw_circle_by_percent(&info, percent);
}
AT_UI_RAM
u32 br23_read_point(struct draw_context *dc, u16 x, u16 y)
{
u32 pixel;
u16 *pdisp = dc->buf;
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
int offset = (y - dc->disp.top) * dc->disp.width + (x - dc->disp.left);
ASSERT((offset * 2 + 1) < dc->len, "dc->len:%d", dc->len);
if ((offset * 2 + 1) >= dc->len) {
return -1;
}
pixel = pdisp[offset];//(dc->buf[offset * 2] << 8) | dc->buf[offset * 2 + 1];
} else {
ASSERT(0);
}
return pixel;
}
__attribute__((always_inline_when_const_args))
AT_UI_RAM
int br23_draw_point(struct draw_context *dc, u16 x, u16 y, u32 pixel)
{
if (dc->data_format == DC_DATA_FORMAT_OSD16) {
int offset = (y - dc->disp.top) * dc->disp.width + (x - dc->disp.left);
/* ASSERT((offset * 2 + 1) < dc->len, "dc->len:%d", dc->len); */
if ((offset * 2 + 1) >= dc->len) {
return -1;
}
dc->buf[offset * 2 ] = pixel >> 8;
dc->buf[offset * 2 + 1] = pixel;
} else if (dc->data_format == DC_DATA_FORMAT_MONO) {
/* ASSERT(x < __this->info.width); */
/* ASSERT(y < __this->info.height); */
if ((x >= __this->info.width) || (y >= __this->info.height)) {
return -1;
}
if (pixel & BIT(31)) {
dc->buf[y / 8 * __this->info.width + x] ^= BIT(y % 8);
} else if (pixel == 0x55aa) {
dc->buf[y / 8 * __this->info.width + x] &= ~BIT(y % 8);
} else if (pixel) {
dc->buf[y / 8 * __this->info.width + x] |= BIT(y % 8);
} else {
dc->buf[y / 8 * __this->info.width + x] &= ~BIT(y % 8);
}
}
return 0;
}
int br23_open_device(struct draw_context *dc, const char *device)
{
return 0;
}
int br23_close_device(int fd)
{
return 0;
}
int ui_fill_rect(struct draw_context *dc, int left, int top, int width, int height, u32 acolor)
{
int i;
int w, h;
u16 color = acolor & 0xffff;
if (!dc->buf) {
return 0;
}
struct rect rect;
rect.left = left;
rect.top = top;
rect.width = width;
rect.height = height;
struct rect cover;
if (!get_rect_cover(&dc->draw, &rect, &cover)) {
return 0;
}
if (dc->data_format == DC_DATA_FORMAT_MONO) {
color = (color == UI_RGB565(BGC_MONO_SET)) ? 0xffff : 0x55aa;
for (h = 0; h < cover.height; h++) {
for (w = 0; w < cover.width; w++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, cover.left + w, cover.top + h, color);
}
}
}
} else {
#if 0
for (h = 0; h < cover.height; h++) {
for (w = 0; w < cover.width; w++) {
if (platform_api->draw_point) {
platform_api->draw_point(dc, cover.left + w, cover.top + h, color);
}
}
}
#else
u16 color16 = (color >> 8) | ((color & 0xff) << 8);
u32 color32 = (color16 << 16) | color16;
h = 0;
u32 *p32 = (u32 *)&dc->buf[(cover.top + h - dc->disp.top) * dc->disp.width * 2 + (cover.left - dc->disp.left) * 2];
u32 *_p32 = p32;
u32 len = cover.width * 2;
if ((u32)p32 % 4) {
u16 *p16 = (u16 *)p32;
*p16++ = color16;
p32 = (u32 *)p16;
len -= 2;
ASSERT((u32)p32 % 4 == 0);
}
u32 count = len / 4;
while (count--) {
*p32++ = color32;
}
count = (len % 4) / 2;
u16 *p16 = (u16 *)p32;
while (count--) {
*p16++ = color16;
}
for (h = 1; h < cover.height; h++) {
u32 *__p32 = (u32 *)&dc->buf[(cover.top + h - dc->disp.top) * dc->disp.width * 2 + (cover.left - dc->disp.left) * 2];
memcpy(__p32, _p32, cover.width * 2);
}
#endif
}
return 0;
}
int ui_draw_image(struct draw_context *dc, int page, int id, int x, int y)
{
dc->draw_img.en = true;
dc->draw_img.x = x;
dc->draw_img.y = y;
dc->draw_img.id = id;
dc->draw_img.page = page;
return br23_draw_image(dc, id, 0, NULL);
}
int ui_draw_ascii(struct draw_context *dc, char *str, int strlen, int x, int y, int color)
{
struct ui_text_attrs text = {0};
text.str = str;
text.format = "ascii";
text.color = color;
text.strlen = strlen;
text.flags = FONT_DEFAULT;
dc->draw_img.en = true;
dc->draw_img.x = x;
dc->draw_img.y = y;
return br23_show_text(dc, &text);
}
int ui_draw_text(struct draw_context *dc, int encode, int endian, char *str, int strlen, int x, int y, int color)
{
struct ui_text_attrs text = {0};
text.str = str;
text.format = "text";
text.color = color;
text.strlen = strlen;
text.encode = encode;
text.endian = endian;
text.flags = FONT_DEFAULT;
dc->draw_img.en = true;
dc->draw_img.x = x;
dc->draw_img.y = y;
return br23_show_text(dc, &text);
}
int ui_draw_strpic(struct draw_context *dc, int id, int x, int y, int color)
{
struct ui_text_attrs text = {0};
u8 strbuf;
strbuf = id;
text.str = &strbuf;
text.format = "strpic";
text.color = color;
text.strlen = 0;
text.encode = 0;
text.endian = 0;
text.flags = 0;
dc->draw_img.en = true;
dc->draw_img.x = x;
dc->draw_img.y = y;
return br23_show_text(dc, &text);
}
int ui_draw_set_pixel(struct draw_context *dc, int x, int y, int pixel)
{
return platform_api->draw_point(dc, x, y, pixel);
}
u32 ui_draw_get_pixel(struct draw_context *dc, int x, int y)
{
return platform_api->read_point(dc, x, y);
}
u16 ui_draw_get_mixed_pixel(u16 backcolor, u16 forecolor, u8 alpha)
{
return get_mixed_pixel(backcolor, forecolor, alpha);
}
static const struct ui_platform_api br23_platform_api = {
.malloc = br23_malloc,
.free = br23_free,
.load_style = br23_load_style,
.load_window = br23_load_window,
.unload_window = br23_unload_window,
.open_draw_context = br23_open_draw_context,
.get_draw_context = br23_get_draw_context,
.put_draw_context = br23_put_draw_context,
.set_draw_context = br23_set_draw_context,
.close_draw_context = br23_close_draw_context,
.load_widget_info = br23_load_widget_info,
.load_css = br23_load_css,
.load_image_list = br23_load_image_list,
.load_text_list = br23_load_text_list,
.fill_rect = br23_fill_rect,
.draw_rect = br23_draw_rect,
.draw_image = br23_draw_image,
.show_text = br23_show_text,
.read_point = br23_read_point,
.draw_point = br23_draw_point,
.invert_rect = br23_invert_rect,
.read_image_info = br23_read_image_info,
.open_device = br23_open_device,
.close_device = br23_close_device,
.set_timer = br23_set_timer,
.del_timer = br23_del_timer,
.file_browser_open = NULL,
.get_file_attrs = NULL,
.set_file_attrs = NULL,
.show_file_preview = NULL,
.move_file_preview = NULL,
.clear_file_preview = NULL,
.flush_file_preview = NULL,
.open_file = NULL,
.delete_file = NULL,
.file_browser_close = NULL,
};
static int open_resource_file()
{
int ret;
printf("open_resouece_file...\n");
ret = open_resfile(RES_PATH"JL.res");
if (ret) {
return -EINVAL;
}
ret = open_str_file(RES_PATH"JL.str");
if (ret) {
return -EINVAL;
}
ret = font_ascii_init(RES_PATH"ascii.res");
if (ret) {
return -EINVAL;
}
return 0;
}
int __attribute__((weak)) lcd_get_scrennifo(struct fb_var_screeninfo *info)
{
info->s_xoffset = 0;
info->s_yoffset = 0;
info->s_xres = 240;
info->s_yres = 240;
return 0;
}
int ui_platform_init(void *lcd)
{
struct rect rect;
struct lcd_info info = {0};
#ifdef UI_BUF_CALC
INIT_LIST_HEAD(&buffer_used.list);
#endif
__this->api = &br23_platform_api;
ASSERT(__this->api->open_draw_context);
ASSERT(__this->api->get_draw_context);
ASSERT(__this->api->put_draw_context);
ASSERT(__this->api->set_draw_context);
ASSERT(__this->api->close_draw_context);
__this->lcd = lcd_get_hdl();
ASSERT(__this->lcd);
ASSERT(__this->lcd->init);
ASSERT(__this->lcd->get_screen_info);
ASSERT(__this->lcd->buffer_malloc);
ASSERT(__this->lcd->buffer_free);
ASSERT(__this->lcd->draw);
ASSERT(__this->lcd->set_draw_area);
ASSERT(__this->lcd->backlight_ctrl);
if (__this->lcd->init) {
__this->lcd->init(lcd);
}
if (__this->lcd->backlight_ctrl) {
__this->lcd->backlight_ctrl(true);
}
if (__this->lcd->get_screen_info) {
__this->lcd->get_screen_info(&info);
}
rect.left = 0;
rect.top = 0;
rect.width = info.width;
rect.height = info.height;
printf("ui_platform_init :: [%d,%d,%d,%d]\n", rect.left, rect.top, rect.width, rect.height);
ui_core_init(__this->api, &rect);
return 0;
}
int ui_style_file_version_compare(int version)
{
int v;
int len;
struct ui_file_head head;
static u8 checked = 0;
if (checked == 0) {
if (!ui_file) {
puts("ui version_compare ui_file null!\n");
ASSERT(0);
return 0;
}
res_fseek(ui_file, 0, SEEK_SET);
len = sizeof(struct ui_file_head);
res_fread(ui_file, &head, len);
printf("style file version is: 0x%x,UI_VERSION is: 0x%x\n", *(u32 *)(head.res), version);
if (*(u32 *)head.res != version) {
puts("style file version is not the same as UI_VERSION !!\n");
ASSERT(0);
}
checked = 1;
}
return 0;
}
/* static const char *WATCH_RES_CHECK_LIST[] = { */
/* RES_PATH"JL/JL.res", */
/* RES_PATH"watch/watch.res", */
/* RES_PATH"watch1/watch1.res", */
/* RES_PATH"watch2/watch2.res", */
/* RES_PATH"watch3/watch3.res", */
/* RES_PATH"watch4/watch4.res", */
/* RES_PATH"watch5/watch5.res", */
/* }; */
/* static const char *WATCH_STR_CHECK_LIST[] = { */
/* RES_PATH"JL/JL.str", */
/* RES_PATH"watch/watch.str", */
/* RES_PATH"watch1/watch1.str", */
/* RES_PATH"watch2/watch2.str", */
/* RES_PATH"watch3/watch3.str", */
/* RES_PATH"watch4/watch4.str", */
/* RES_PATH"watch5/watch5.str", */
/* }; */
int ui_watch_poweron_update_check()
{
#if(CONFIG_UI_STYLE == STYLE_JL_WTACH)
//如果上次表盘升级异常,直接进入表盘升级模式等待升级完成
//加入新标志位的判断,用于升级过程中断电后开机进入升级模式的情况
if (smartbox_eflash_flag_get() != 0 ||
smartbox_eflash_update_flag_get()) {
printf("\n\ngoto watch update mode\n\n");
//上电后,发现上一次表盘升级异常,先初始化升级需要的蓝牙相关部分,
//再跳转到升级模式
watch_update_over = 2;
app_smartbox_task_prepare(0, SMARTBOX_TASK_ACTION_WATCH_TRANSFER, 0);
/* app_task_switch_to(APP_WATCH_UPDATE_TASK); */
return -1;
/* while (watch_update_over == 2) { */
/* os_time_dly(3); */
/* } */
/* watch_update_over = 0; */
}
#endif
return 0;
}
int ui_upgrade_file_check_valid()
{
#if UI_UPGRADE_RES_ENABLE
//简单实现
//假设升级界面必须存在,调用了该接口证明资源不完整
//需要进行升级
smartbox_eflash_flag_set(1);//这个标志的清理需要注意
return 0;
#endif
return -ENOENT;
}
int ui_file_check_valid()
{
#if UI_WATCH_RES_ENABLE
int ret;
printf("open_resouece_file...\n");
int i = 0;
FILE *file = NULL;
char *sty_suffix = ".sty";
char *res_suffix = ".res";
char *str_suffix = ".str";
char tmp_name[100];
/* u32 list_len = sizeof(WATCH_STY_CHECK_LIST) / sizeof(WATCH_STY_CHECK_LIST[0]); */
u32 list_len;
u32 tmp_strlen;
u32 suffix_len;
//如果上次表盘升级异常,直接进入表盘升级模式等待升级完成
if (smartbox_eflash_flag_get() != 0 ||
smartbox_eflash_update_flag_get()) {
printf("\n\nneed goto watch update mode\n\n");
return -EINVAL;
} else {
ret = watch_set_init();
if (ret != 0) {
return -EINVAL;
}
}
list_len = watch_items;
for (i = 0; i < list_len; i++) {
if (file) {
res_fclose(file);
file = NULL;
}
/* file = res_fopen(WATCH_STY_CHECK_LIST[i], "r"); */
file = res_fopen(watch_res[i], "r");
if (!file) {
return -ENOENT;
}
}
suffix_len = strlen(sty_suffix);
close_resfile();
for (i = 0; i < list_len; i++) {
memset(tmp_name, 0, sizeof(tmp_name));
/* tmp_strlen = strlen(WATCH_STY_CHECK_LIST[i]); */
/* strcpy(tmp_name, WATCH_STY_CHECK_LIST[i]); */
tmp_strlen = strlen(watch_res[i]);
strcpy(tmp_name, watch_res[i]);
strcpy(&tmp_name[tmp_strlen - suffix_len], res_suffix);
tmp_name[tmp_strlen - suffix_len + strlen(res_suffix)] = '\0';
/* ret = open_resfile(WATCH_RES_CHECK_LIST[i]); */
ret = open_resfile(tmp_name);
if (ret) {
return -EINVAL;
}
close_resfile();
}
close_str_file();
for (i = 0; i < list_len; i++) {
memset(tmp_name, 0, sizeof(tmp_name));
/* tmp_strlen = strlen(WATCH_STY_CHECK_LIST[i]); */
/* strcpy(tmp_name, WATCH_STY_CHECK_LIST[i]); */
tmp_strlen = strlen(watch_res[i]);
strcpy(tmp_name, watch_res[i]);
strcpy(&tmp_name[tmp_strlen - suffix_len], str_suffix);
tmp_name[tmp_strlen - suffix_len + strlen(str_suffix)] = '\0';
/* ret = open_str_file(WATCH_STR_CHECK_LIST[i]); */
ret = open_resfile(tmp_name);
if (ret) {
return -EINVAL;
}
close_str_file();
}
#endif
return 0;
}
#endif