#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[] = { {-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; } 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; ui_file = ui_file1; if (!_head) { struct ui_style style = {0}; int load_style = 1; last_page = page; 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); */ 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); */ 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); */ 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); 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; } 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() { return 0; } #endif