Files
player/Project/Src/MyWin/mywin_cfg.c
2025-10-12 17:01:37 +08:00

359 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 <zlib.h>
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;
}
}