KT24-1110_65E-HA-651B/cpu/br25/ui_driver/interface/ui_platform.c

2897 lines
88 KiB
C
Raw Permalink Normal View History

2024-11-10 10:44:17 +00:00
#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