469 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			469 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include "mywin_inc.h" 
 | |||
|  | #include "rtthread.h"
 | |||
|  | #include "main.h"
 | |||
|  | #include "system_updata.h"
 | |||
|  | #include "system_file.h"
 | |||
|  | #include "lcd_rgb.h"
 | |||
|  | 
 | |||
|  | #include "char_encode.h"
 | |||
|  | 
 | |||
|  | #include "ft2build.h"
 | |||
|  | #include FT_FREETYPE_H
 | |||
|  | 
 | |||
|  | #include "ff.h"
 | |||
|  | #include "picdeco.h"
 | |||
|  | #include "bmp.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[3]={0}; | |||
|  | 	u8 uni[3]={0}; | |||
|  | 	 | |||
|  | 	if (word>0x80) | |||
|  | 	{ | |||
|  | 		gbk[0]=word>>8; | |||
|  | 		gbk[1]=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; | |||
|  | 	} | |||
|  | } | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 | |||
|  | 
 |