2897 lines
88 KiB
C
2897 lines
88 KiB
C
#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
|
||
|