#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