#include "lcd_rgb.h" #include "main.h" #include "mywin_inc.h" #include "rtthread.h" #include "system_file.h" #include "system_updata.h" #include "char_encode.h" #include "ft2build.h" #include FT_FREETYPE_H #include "bmp.h" #include "ff.h" #include "picdeco.h" #include "png.h" #include static FT_Library g_ft_library = 0; static FT_Face g_ft_face = 0; void WIN_FontInit(char *path, char *en_path) { FT_Error ft_error = 0; FT_Face ft_face = 0; if (g_ft_library == 0) ft_error = FT_Init_FreeType(&g_ft_library); if (ft_error == 0) { ft_error = FT_New_Face(g_ft_library, path, 0, &ft_face); if (ft_error == 0) { if (g_ft_face) { FT_Done_Face(g_ft_face); g_ft_face = 0; } g_ft_face = ft_face; } } } static unsigned int g_WinTime = 0; // 一毫秒中断 static void WIN_TimerAdd1msIrq(void) { g_WinTime++; } // 获取从上次获取时间算起过去了多少毫秒 unsigned int WIN_GetTimePast(void) { unsigned int ret = g_WinTime; g_WinTime = 0; return ret; } // 初始化配置 void WIN_InitCfg(void) { // 配置一毫秒的定时器 TIMER_InitStruct timer_init = {0}; timer_init.Cycle = 1000; timer_init.Tim = TIM2; timer_init.UpdataCall = WIN_TimerAdd1msIrq; TIMER_InitNormal(&timer_init); // 配置LCD接口函数 static WIN_LcdInterFaceFunStruct g_lcd = {0}; WIN_Struct *ewin = WIN_GetWinStruct(); g_lcd.Init = LCD_Init; g_lcd.drawPoint = (void (*)(int, int, int))LCD_DrawPointSafe; g_lcd.drawPointColor = LCD_DrawPointSafeColor; g_lcd.drawPointColorAlpha = LCD_DrawPointSafeColorAlpha; g_lcd.clearRect = LCD_ClearRect; g_lcd.fillRectByColor = LCD_FillRectByColor; g_lcd.fillRectByColorAlpha = LCD_FillRectByColorAlpha; g_lcd.fillRectOffAt = LCD_FillRectOff16At; g_lcd.fillRectOffAtAlpha = LCD_FillRectOffAtAlpha; g_lcd.getColors = LCD_GetColors; g_lcd.getPointColor = 0; g_lcd.enterLayerBuff = LCD_EnterLayerBuff; g_lcd.exitLayerBuff = LCD_ExitLayerBuff; // g_lcd.setScreenDis=LCD_SetScreenDis; g_lcd.setWindow = LCD_SetWindow; g_lcd.setDrawMode = LCD_SetLcdDrawMode; g_lcd.getLcdSizeX = LCD_GetLcdSizeX; g_lcd.getLcdSizeY = LCD_GetLcdSizeY; // g_lcd.getWindowSizeX=LCD_GetWindowSizeX; // g_lcd.getWindowSizeY=LCD_GetWindowSizeY; g_lcd.getLcdColor = (u16 (*)(void))LCD_GetLcdColor16; g_lcd.getLcdBkColor = (u16 (*)(void))LCD_GetLcdBkColor16; g_lcd.setLcdColor = (u16 (*)(u16))LCD_SetLcdColor16; g_lcd.setLcdBkColor = (u16 (*)(u16))LCD_SetLcdBkColor16; ewin->lcd = &g_lcd; // 字体初始化 WIN_FontInit("simfang.ttf", 0); // WIN_FontInit("0:/ttf/simsun6.ttc",0); // WIN_FontInit("0:/ttf/华文中宋.ttf","0:/ttf/Agency-FB.ttf"); WIN_FontDrawFunStruct *font = &WIN_GetWinStruct()->font; // font->malloc=mymalloc_ccm; // font->free=myfree_ccm; font->malloc = mymalloc_exm; font->free = myfree; // 设置默认字体 WIN_SetFontSize(24); WIN_SetFontType(WIN_FONT_TYPE_NORMAL); } // 供MYWIN调用的延时函数 void WIN_Delay_ms(u32 ms) { rt_thread_delay(ms); } // 使用信号量对GUI线程的访问进行保护 #if 0 static struct rt_semaphore g_gui={0}; static rt_err_t g_gui_err=RT_ERROR; #define GUI_CREAT() \ { \ g_gui_err = rt_sem_init(&g_gui, "g_gui", 1, RT_IPC_FLAG_FIFO); \ rt_sem_take(&g_gui, RT_WAITING_FOREVER); \ } #define GUI_DELETE() \ { \ g_gui_err = rt_sem_release(&g_gui); \ if (g_gui_err == RT_EOK) \ rt_sem_detach(&g_gui); \ } #define GUI_WAIT() \ { \ while (g_gui_err == RT_ERROR) \ rt_thread_delay(10); \ rt_sem_take(&g_gui, RT_WAITING_FOREVER); \ } #define GUI_WAIT_END() \ { \ } #else #define GUI_CREAT() \ { \ } #define GUI_WAIT() \ { \ } #define GUI_DELETE() \ { \ } #define GUI_WAIT_END() \ { \ } #endif // 根据句柄删除线程 static int WIN_DeleteThread(WIN_ThreadHandle *handle); // GUI扩展线程 static void g_guiExThread(void *ptr) { GUI_CREAT(); WIN_WorkFunStruct *p = ptr; *p->ret = p->fun(p->ptr); p->done = 1; // 标记运行结束 GUI_DELETE() WIN_DeleteThread(p->handle); } // 获取工作线程运行状态,1,运行结束 int WIN_GetExWorkFunStat(WIN_WorkFunStruct *w) { int ret = -1; GUI_WAIT(); ret = w->done; GUI_WAIT_END() return ret; } // 供MYWIN调用的创建线程函数,创建成功返回工作空间结构体 // fun是工作函数,ptr是传送给工作函数的参数,ret是工作函数的返回值 WIN_WorkFunStruct *WIN_CreatThread(int (*fun)(void *), void *ptr, int *ret) { WIN_ThreadHandle *handle = mymalloc(sizeof(WIN_ThreadHandle)); mymemset(handle, 0, sizeof(WIN_ThreadHandle)); handle->tackSize = 4096; handle->tack = mymalloc(handle->tackSize); WIN_WorkFunStruct *work = mymalloc(sizeof(WIN_WorkFunStruct)); mymemset(work, 0, sizeof(WIN_WorkFunStruct)); work->fun = fun; work->handle = handle; work->ptr = ptr; work->ret = ret; rt_thread_init(&handle->thread, "g_guiExThread", g_guiExThread, work, handle->tack, handle->tackSize, 21, 100); rt_thread_startup(&handle->thread); return work; } // 供MYWIN调用的创建线程函数,创建成功返回工作空间结构体 // fun是工作函数,ptr是传送给工作函数的参数,ret是工作函数的返回值 WIN_WorkFunStruct *WIN_CreatThreadPro(int (*fun)(void *), void *ptr, int *ret, u8 pro) { WIN_ThreadHandle *handle = mymalloc(sizeof(WIN_ThreadHandle)); mymemset(handle, 0, sizeof(WIN_ThreadHandle)); handle->tackSize = 4096; handle->tack = mymalloc(handle->tackSize); WIN_WorkFunStruct *work = mymalloc(sizeof(WIN_WorkFunStruct)); mymemset(work, 0, sizeof(WIN_WorkFunStruct)); work->fun = fun; work->handle = handle; work->ptr = ptr; work->ret = ret; rt_thread_init(&handle->thread, "g_guiExThread", g_guiExThread, work, handle->tack, handle->tackSize, pro, 80); rt_thread_startup(&handle->thread); return work; } // 根据句柄删除线程,这个函数由 g_guiExThread 线程函数调用 static int WIN_DeleteThread(WIN_ThreadHandle *handle) { return 0; } // 线程所用资源回收函数,由发起线程调用 void WIN_ExWorkFunClear(WIN_WorkFunStruct *w) { myfree(w->handle->tack); myfree(w->handle); myfree(w); } // 解码png图片,成功返回1,失败返回0 static int decode_png(WIN_PicStruct *pic, const char *name) { int png_err = 0; png_image image; /* The control structure used by libpng */ /* Initialize the 'png_image' structure. */ memset(&image, 0, (sizeof image)); image.version = PNG_IMAGE_VERSION; /* The first argument is the file to read: */ if (png_image_begin_read_from_file(&image, name) != 0) { image.format = PNG_FORMAT_BGRA; pic->data = mymalloc_exm(PNG_IMAGE_SIZE(image)); pic->format = PIC_FORMAT_ARGB8888; pic->xsize = image.width; pic->ysize = image.height; if (png_err = png_image_finish_read(&image, NULL /*background*/, pic->data, 0 /*row_stride*/, NULL /*colormap*/), png_err != 0) { return 1; } else { myfree(pic->data); return 0; } } return 0; } // 解码图片0,成功,1,失败 int WIN_DecodeImg(WIN_PicStruct *pic, const char *name) { // 判断图片格式 int str_len = strlen(name); const char *p_str = &name[str_len - 4]; // 解码时显示提示,这个函数是阻塞的 if (strcmp(p_str, ".png") == 0) { if (decode_png(pic, name) == 1) return 0; } else if (strcmp(p_str, ".jpg") == 0) { int ret = 0; BITMAP_Struct bmp = {0}; ret = JPEG_Decode((const u8 *)name, &bmp); if (ret == 0) { pic->data = bmp.buff; pic->xsize = bmp.x_size; pic->ysize = bmp.y_size; pic->format = PIC_FORMAT_RGB565; return 0; } } else if (strcmp(p_str, ".bmp") == 0) { int ret = 0; BMP_DecodeStruct bmp = {0}; ret = BMP_Decode((const u8 *)name, &bmp); if (ret == 0) { pic->data = bmp.data; pic->xsize = bmp.x_size; pic->ysize = bmp.y_size; pic->format = PIC_FORMAT_RGB565; return 0; } } else if (strcmp(p_str, ".pic") == 0) { u8 *data = SysFile_GetFileByName((char *)name, 0); if (data) { WIN_GetImageSize(data, &pic->xsize, &pic->ysize); u8 *t = mymalloc(pic->xsize * pic->ysize * 2); mymemcpy(t, data + 8, pic->xsize * pic->ysize * 2); pic->format = PIC_FORMAT_RGB565; pic->data = (u16 *)t; myfree(data); return 0; } } return 1; } // 根据字体类型获取字模数据 int WIN_GetWordData(u8 size, u8 type, unsigned char *buff, int word, int buff_size) { u8 gbk[4] = {0}; u8 uni[3] = {0}; if (word > 0x80) { gbk[0] = (word >> 8) & 0xff; gbk[1] = (word >> 0) & 0xff; // gbk[2]=word&0xff; } else { gbk[0] = word; } gbk2uni_str(gbk, uni); if (g_ft_face) { FT_Error ft_error = 0; load_char: ft_error = FT_Set_Pixel_Sizes(g_ft_face, size, size); if (type == WIN_FONT_TYPE_BITMAP) ft_error = FT_Load_Char(g_ft_face, (uni[0] << 8) | uni[1], FT_LOAD_RENDER | FT_LOAD_MONOCHROME); else ft_error = FT_Load_Char(g_ft_face, (uni[0] << 8) | uni[1], FT_LOAD_RENDER); // if(ft_error) // { // printf("%s:err,ft_error=0x%02x,c=%s,uni=%02x,%02x\r\n",__func__,ft_error,gbk,uni[0],uni[1]); // WIN_FontInit("华文中宋.ttf",0); // goto load_char; // } FT_GlyphSlot slot = g_ft_face->glyph; int w_byte = slot->bitmap.pitch; u8 *buf = slot->bitmap.buffer; mymemcpy(buff, buf, buff_size - 5); buff[buff_size - 5] = slot->bitmap.width; buff[buff_size - 4] = slot->bitmap.rows; buff[buff_size - 3] = slot->bitmap.pitch; buff[buff_size - 2] = slot->bitmap_left; buff[buff_size - 1] = slot->bitmap_top; return slot->bitmap.width; } else { mymemset(buff, 0xf0, buff_size - 5); buff[buff_size - 5] = size; buff[buff_size - 4] = size; buff[buff_size - 3] = size / 8 + (size % 8) ? 1 : 0; buff[buff_size - 2] = 0; buff[buff_size - 1] = 0; return size; } }