#include "LT768_Lib.h"
#include "Winbond.h"

//extern SSI_HandleTypeDef SSIHandle;
//extern DMAC_HandleTypeDef hdma;
extern DMAC_HandleTypeDef hdma2;

unsigned char Font_1[Font_BYTE]={0};

unsigned char TFT_color = 0;     //判断是那种颜色排列
unsigned char Flash_type = 0;    //0:NorFlash  ，1:NandFlash

unsigned short LCD_XSIZE_TFT = 800;
unsigned short LCD_YSIZE_TFT = 480;
unsigned short LCD_VBPD = 0;
unsigned short LCD_VFPD = 0;
unsigned short LCD_VSPW = 0;
unsigned short LCD_HBPD = 0;
unsigned short LCD_HFPD = 0;
unsigned short LCD_HSPW = 0;

unsigned char 		 gPCLKRISING = 0;
unsigned char 		 gHSYNCPolarity = 0;
unsigned char 		 gVSYNCPolarity = 0;
unsigned char 		 gDEPolarity = 0;

volatile unsigned int Lay_Canvas_Addr = 0x80000000;
volatile unsigned short Lay_Canvas_Width = 800;

#define BAUDRATE_ADDR  0x00000402    //3byte
#define XY_SIZE_ADDR   0x0000040a    //4byte
#define LCD_PARAM_ADDR 0x0000040e    //12byte
#define LCDRotate_ADDR 0x0000042A

unsigned int gBaudrate = 0;
extern unsigned char init_ok_flag;

SSI_HandleTypeDef SSIHandle;
DMAC_HandleTypeDef hdma;
DMAC_HandleTypeDef hdma2;

HAL_StatusTypeDef DMAC_QUAD_SSI_read(uint32_t addr, uint32_t *buf)
{
	uint32_t tmp_add;
	hdma.init.dst_addr = (uint32_t)buf;
	HAL_DMAC_Init(&hdma);
	DRV_SSI_QUAD_DMA_Trig(SSI2,QUAD_READ_CMD,addr,DMACR_RDMAE);
	HAL_DMAC_StartPolling(&hdma);
	HAL_DMAC_PollForTransfer(&hdma, 0, HAL_MAX_DELAY);
	return (HAL_OK);
}

void DMAC_M2MTest2(DMAC_TypeDef *pdmac,uint32_t ch,uint32_t len,uint8_t *dstbuf,uint8_t *srcbuf)
{
    uint32_t i;
	if(hdma2.init.transfer_size==0)	return;
	
	hdma2.init.dst_addr = (uint32_t)dstbuf;
	hdma2.init.src_addr = (uint32_t)srcbuf;
    /*初始化DMAC*/
    HAL_DMAC_Init(&hdma2);
    /*开启非中断模式DMAC传输*/
    HAL_DMAC_StartPolling(&hdma2);
    /*轮询传输完成*/
    HAL_DMAC_PollForTransfer(&hdma2, 0, HAL_MAX_DELAY);
}
void DMAC_M2MTest3(DMAC_TypeDef *pdmac,uint32_t ch,uint32_t len,uint8_t *dstbuf,uint8_t *srcbuf)
{
    uint32_t i;
	if(hdma2.init.transfer_size==0)	return;
	
	hdma2.init.dst_addr = (uint32_t)dstbuf;
	hdma2.init.src_addr = (uint32_t)srcbuf;
    /*初始化DMAC*/
    HAL_DMAC_Init(&hdma2);
    /*开启非中断模式DMAC传输*/
    HAL_DMAC_StartPolling(&hdma2);
    /*轮询传输完成*/
//    HAL_DMAC_PollForTransfer(&hdma2, 0, HAL_MAX_DELAY);
}

void LT_ReadParam(void)
{
	unsigned char temp[25] = {0};
	u32 ID = 0;
	
	Flash_type = 0;	
	ID = W25QXX_ReadID_STD();
	if((ID<=0xEF18 && ID>=0xEF13 ) || ID==0x5e17)
	{	
		printf("ID1:%x \r\n",ID);
		if(ID == 0xEF18)
		{
			W25Q256 = 1;
			W25QXX_Enter_4Byte_AddressMode_STD();
		}
	}
	else
	{
		Flash_type = 1;
		ID=W25NXX_ReadID();
		printf("ID2:%x \r\n",ID);		
	}
	printf("type:%d \r\n",Flash_type);
	
	LT_ReadFlash(ENDBYTE_Buf,ENDBYTE_ADDR,1);
	if( ENDBYTE_Buf[1]==0xFF && ENDBYTE_Buf[2]==0xFF && ENDBYTE_Buf[3]==0xFF) 
	{
		if(ENDBYTE_Buf[0]==0xFF || ENDBYTE_Buf[0]==0x00)  //UI_Editor 0x00,uartTFT 0xFF
		{
			ENDBYTE_Buf[0]=0xE4;
			ENDBYTE_Buf[1]=0x1B;	
			ENDBYTE_Buf[2]=0x11;
			ENDBYTE_Buf[3]=0xEE;
		}
	}

	LT_ReadFlash(temp,BAUDRATE_ADDR,3);
	if(temp[0] == 0xFF && temp[1] == 0xFF && temp[2] == 0xFF)
	{
		printf("%x   %x    %x\r\n",temp[0],temp[1],temp[2]);
		gBaudrate = 115200;
		LCD_XSIZE_TFT = 800;
		LCD_YSIZE_TFT = 480;
		LCD_VBPD = 23;
		LCD_VFPD = 22;
		LCD_VSPW = 3;
		LCD_HBPD = 46;
		LCD_HFPD = 210;
		LCD_HSPW = 20;
		gPCLKRISING = 1;
		gHSYNCPolarity = 0;
		gVSYNCPolarity = 0;
		gDEPolarity = 1;
		
		TFT_color = 0;
		init_ok_flag = 1;
	}
	else
	{
		gBaudrate = temp[0];
		gBaudrate = (gBaudrate<<8) + temp[1];
		gBaudrate = (gBaudrate<<8) + temp[2];
		printf("rate:%d\r\n",gBaudrate);
		
		LT_ReadFlash(temp,XY_SIZE_ADDR,4);
		LCD_XSIZE_TFT = temp[0];
		LCD_XSIZE_TFT = (LCD_XSIZE_TFT<<8) + temp[1];
		LCD_YSIZE_TFT = temp[2];
		LCD_YSIZE_TFT = (LCD_YSIZE_TFT<<8) + temp[3];
		printf("w:%d   h:%d\r\n",LCD_XSIZE_TFT,LCD_YSIZE_TFT);
		
		LT_ReadFlash(temp,LCD_PARAM_ADDR,23);
		LCD_VBPD = temp[0];
		LCD_VBPD = (LCD_VBPD<<8) + temp[1];
		LCD_VFPD = temp[2];
		LCD_VFPD = (LCD_VFPD<<8) + temp[3];
		LCD_VSPW = temp[4];
		LCD_VSPW = (LCD_VSPW<<8) + temp[5];
		LCD_HBPD = temp[6];
		LCD_HBPD = (LCD_HBPD<<8) + temp[7];
		LCD_HFPD = temp[8];
		LCD_HFPD = (LCD_HFPD<<8) + temp[9];
		LCD_HSPW = temp[10];
		LCD_HSPW = (LCD_HSPW<<8) + temp[11];
		
		gPCLKRISING    = temp[12];
		gHSYNCPolarity = temp[13];
		gVSYNCPolarity = temp[14];
		gDEPolarity    = temp[15];
		
		TFT_color = temp[16];
		/*Flash_type = temp[18];*/ //printf("Flash:%d \r\n",Flash_type);
		LT_ReadFlash(&R_angle,LCDRotate_ADDR,1);
		printf("R_angle:%d \r\n",R_angle);
		init_ok_flag = 0;
	}
//		LCD_XSIZE_TFT = 1024;
//		LCD_YSIZE_TFT = 600;
//		LCD_VBPD = 3;
//		LCD_VFPD = 3;
//		LCD_VSPW = 3;
//		LCD_HBPD = 100;
//		LCD_HFPD = 116;
//		LCD_HSPW = 40;
//		
//		gPCLKRISING = 0;
//		gHSYNCPolarity = 0;
//		gVSYNCPolarity = 0; 
//		gDEPolarity = 1;
		
//		LCD_XSIZE_TFT = 480;
//		LCD_YSIZE_TFT = 272;
//		LCD_VBPD = 12;
//		LCD_VFPD = 8;
//		LCD_VSPW = 4;
//		LCD_HBPD = 43;
//		LCD_HFPD = 8;
//		LCD_HSPW = 4;		
	
		printf("LCD_VBPD:%d\r\n",LCD_VBPD);
		printf("LCD_VFPD:%d\r\n",LCD_VFPD);
		printf("LCD_VSPW:%d\r\n",LCD_VSPW);
		printf("LCD_HBPD:%d\r\n",LCD_HBPD);
		printf("LCD_HFPD:%d\r\n",LCD_HFPD);
		printf("LCD_HSPW:%d\r\n",LCD_HSPW);
		
		printf("gPCLKRISING:%d\r\n",gPCLKRISING);
		printf("gHSYNCPolarity:%d\r\n",gHSYNCPolarity);
		printf("gVSYNCPolarity:%d\r\n",gVSYNCPolarity);
		printf("gDEPolarity:%d\r\n",gDEPolarity);

}

void Main_Image_Start_Address(unsigned long Addr)	
{

}
//[24h][25h]=========================================================================
void Main_Image_Width(unsigned short WX)	
{

}

void Main_Window_Start_XY(unsigned short WX,unsigned short HY)	
{

}

void Active_Window_XY(unsigned short WX,unsigned short HY)	
{

}
//[5Ah][5Bh][5Ch][5Dh]=========================================================================
void Active_Window_WH(unsigned short WX,unsigned short HY)	
{

}

void Canvas_Image_Start_address(unsigned int Addr)	
{
	Lay_Canvas_Addr = Addr;
}

void Canvas_image_width(unsigned short WX)	
{
	Lay_Canvas_Width = WX;
}

void LT768_DMA_24bit_Block_Init(void)
{
	uint32_t temp_add;
	
	SSIHandle.Instance = SSI2;
	HAL_SSI_DeInit(&SSIHandle);
	

//	SSIHandle.Init.DFS = DFS_32_BIT;
//	SSIHandle.Init.Format = QUAD_mode;
//	SSIHandle.Init.NDF = LCD_XSIZE_TFT/2 - 1;	//
//	SSIHandle.Init.SSI_QUAD_BaudRatePrescaler = 0x02;	//SSI_DUAL_QUAD_baund
//	SSIHandle.Init.TMOD = RX_ONLY;
//	SSIHandle.Init.Transfer_start_FIFO_level = 0x01;
//	SSIHandle.Init.Transmit_FIFO_Threshold = 0;
//	SSIHandle.Init.Receive_FIFO_Threshold = 0x07;
//	SSIHandle.Init.Address_Length = ADDR_L24;
//	SSIHandle.Init.Instruction_length = INST_L8;
//	SSIHandle.Init.WAIT_CYCLES = 8;
//	SSIHandle.Init.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;
//	HAL_SSI_Init(&SSIHandle, ssi_timeout);

	SPI5.Address_Length = ADDR_L16;
	SPI5.Instruction_length = INST_L8;
	SPI5.WAIT_CYCLES = 8;
	SPI5_Quad_Read_Init();	

	hdma.instance = DMAC2;
	HAL_DMAC_Deinit(&hdma);
	hdma.init.channel_num = 0;
	hdma.init.dst_msize = HAL_DMAC_MSIZE_1;
	hdma.init.src_msize = HAL_DMAC_MSIZE_1;
	hdma.init.dst_inc = HAL_DMAC_SINC_INC;
	hdma.init.src_inc = HAL_DMAC_DINC_NO_CHANGE;
	hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;

	hdma.init.transfer_type = HAL_DMAC_TRANSFERTYPE_P2M_CONTROLLER_DMA;
	hdma.init.peripheral_type = HAL_DMAC2_PERIPHERAL_SSI2_RX;
	hdma.init.transfer_lli = HAL_DMAC_LLP_DIS;
	temp_add = (uint32_t)(&SSI2->DR);
	hdma.init.src_addr = temp_add;
	hdma.init.transfer_size = LCD_XSIZE_TFT/2;	//	
	HAL_DMAC_Init(&hdma);
}

void LT768_BTE_Init(void)
{
	hdma2.instance = DMAC1;
	hdma2.init.channel_num = 0;//HAL_DMACC_CHANNEL_0;
    /*复位DMAC*/
    HAL_DMAC_Deinit(&hdma2);
	hdma2.init.dst_msize = HAL_DMAC_MSIZE_1;
	hdma2.init.src_msize = HAL_DMAC_MSIZE_1;
	hdma2.init.dst_inc = HAL_DMAC_DINC_INC;
	hdma2.init.src_inc = HAL_DMAC_SINC_INC;
	hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.transfer_type = HAL_DMAC_TRANSFERTYPE_M2M_CONTROLLER_DMA;
	hdma2.init.peripheral_type = 0;
	hdma2.init.transfer_lli = HAL_DMAC_LLP_DIS;
	hdma2.init.transfer_size = LCD_XSIZE_TFT/2;;	
	HAL_DMAC_Init(&hdma2);
}

#define LEN_TEST 2048
//__align(4) u8 disBuf[800*480*2] __attribute__ ((at(0x80000000)))= {0};

void LT768_DMA_24bit_Block_Or_Line_16bpp
( 
 unsigned char SCS
,unsigned char Clk
,unsigned short X1
,unsigned short Y1
,unsigned short X_W	
,unsigned short Y_H
,unsigned short P_W
,unsigned int Addr	
,unsigned int lay0        // 层的地址	
,unsigned short canvas_w     // 图层宽度
)
{
	u16 i;
	u32 time;
	
	u16 byte_width;
	
	u8 end_remain;
	u32 addr_sdram;
	u8 start_remain;
	
	if(X_W==0 || Y_H==0)	return ;
	
	if(W25Q256)
		SPI5.Address_Length = ADDR_L32;
	else
		SPI5.Address_Length = ADDR_L24;
	
	addr_sdram=lay0+X1*2;
	if(addr_sdram%4==0)
	{
		start_remain=0;
		if(X_W%2==0)
			end_remain=0;
		else
			end_remain=1;
		byte_width=X_W/2;
	}		
	else	
	{
		start_remain=1;
		if(X_W%2==0)
			end_remain=1;
		else
			end_remain=0;
		byte_width=(X_W-1)/2;
	}	
//	InitTickTime();
	
	if(Flash_type==0)
	{
		for (i = 0; i < Y_H; i++)
		{
			if(start_remain==0)
			{										
				SPI5.DFS = DFS_32_BIT;
				SPI5.NDF = byte_width - 1;
				SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
				SPI5.Instruction_length = INST_L8;
				SPI5.WAIT_CYCLES = 8;   
				SPI5_Quad_Read_Init();			
				SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2),0x6B,Addr+X_W*2*i,byte_width,32,QUAD_mode,0);
				
				if(end_remain)
				{				
					SPI5.DFS = DFS_16_BIT;
					SPI5.NDF = 1 - 1;
					SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
					SPI5.Instruction_length = INST_L8;
					SPI5.WAIT_CYCLES = 8;   
					SPI5_Quad_Read_Init();			
					SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2),0x6B,Addr+X_W*2*(i+1)-2,1,16,QUAD_mode,0);
				}			
			}
			else if(start_remain==1)
			{				
				SPI5.DFS = DFS_16_BIT;
				SPI5.NDF = 1 - 1;
				SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
				SPI5.Instruction_length = INST_L8;
				SPI5.WAIT_CYCLES = 8;    
				SPI5_Quad_Read_Init();			
				SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2),0x6B,Addr+X_W*2*i,1,16,QUAD_mode,0);			

				SPI5.DFS = DFS_32_BIT;
				SPI5.NDF = byte_width - 1;
				SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
				SPI5.Instruction_length = INST_L8;
				SPI5.WAIT_CYCLES = 8;   
				SPI5_Quad_Read_Init();			
				SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+2),0x6B,Addr+X_W*2*i+2,byte_width,32,QUAD_mode,0);
				
				if(end_remain)
				{				
					SPI5.DFS = DFS_16_BIT;
					SPI5.NDF = 1 - 1;
					SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
					SPI5.Instruction_length = INST_L8;
					SPI5.WAIT_CYCLES = 8;   
					SPI5_Quad_Read_Init();			
					SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2),0x6B,Addr+X_W*2*(i+1)-2,1,16,QUAD_mode,0);				
				}			
			}
		}		
	}
	else if(Flash_type==1)
	{
		uint16_t ReadNum = 0;         //读取每一页的数据量
		uint16_t ColumnAddr;          //业内地址
		uint32_t PageAddr;
		uint32_t RemainNum;
		
		uint32_t ReadAddr;
		uint32_t BufferAddr;
		uint16_t offset;
		
		unsigned short page,endpage,remainder,P_W4 = 0;
		unsigned short X_W4=0;
		unsigned short i=0;
		unsigned int addr_temp;
		unsigned short page_remain;
		remainder = Addr%2048;//图片在一页中的起始位置
		page = (Addr/2048);//图片起始地址所在的页编号（页地址）
		if(P_W % 4 != 0)
		{
			P_W4 = (P_W / 4) * 4 + 4;
		}
		else
		{
			P_W4 = P_W;
		}
		endpage = ((Addr+P_W4 * Y_H * 2)/2048);
		
//		if(remainder % 4 != 0)
//		{
//			remainder = (remainder / 4) * 4 + 4;
//		}
		
		BufferAddr = LAY_BUFF4 - remainder;
		if(X1%2)	BufferAddr+=2;		
		
		W25NXX_ContinuousRead_Mode();
//		W25N01GV_PageRead_Mode();
		Write_Page(page);
//		

		CS_FLash_RESET();
		SSI2_ReadWriteByte(0x6B);
		SSI2_ReadWriteByte(0x00);
		SSI2_ReadWriteByte(0x00);
		SSI2_ReadWriteByte(0x00);
		SSI2_ReadWriteByte(0x00);			
		
		offset=BufferAddr%4;
		if(offset)
		{
			SPI5.DFS = DFS_08_BIT;      				//数据帧位数格式
			SPI5.NDF = (4-offset)-1;
			SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler_for_NandFlash;
			SPI5.Address_Length = ADDR_L0;
			SPI5.Instruction_length = INST_L0;
			SPI5.WAIT_CYCLES = 0;
			SPI5_Quad_Read_Init();	
			SSI2_DMA_RX_Continue((unsigned char*)BufferAddr,0x6B,0,(4-offset),8,QUAD_mode,0);
			BufferAddr = BufferAddr+(4-offset);			
		}
		
		SPI5.DFS = DFS_32_BIT;      				//数据帧位数格式
		SPI5.NDF = LEN_TEST-1;
		SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler_for_NandFlash;
		SPI5.Address_Length = ADDR_L0;
		SPI5.Instruction_length = INST_L0;
		SPI5.WAIT_CYCLES = 0;
		SPI5_Quad_Read_Init();
		
		
		for(i=0;i<(endpage-page+1);i+=4)
		{			
			addr_temp = BufferAddr+2048*i;
			SSI2_DMA_RX_Continue((unsigned char*)addr_temp,0x6B,0,LEN_TEST,32,QUAD_mode,0);						
		}
		CS_FLash_SET();
		SPI5_STD_Init(); 								//切回单线
		W25N01GV_PageRead_Mode();
//		W25NXX_Wait_Busy();

		LT768_BTE_Memory_Copy(LAY_BUFF4,P_W4,X1%2,0,
											LAY_BUFF4,P_W4,X1%2,0,
											lay0,canvas_w,X1,Y1,
											0x0c,X_W,Y_H											//显示不去背景色图片
										 );		
		
//		for (i = 0; i < Y_H; i++)
//		{
//			W25NXX_Read_NoCheck((unsigned char *)(Default_BUFF+2048*i),Addr+2048*i,2048,4);			
//		}

//		for(i=0;i<(endpage-page+1);i+=1)
//		{
//			W25NXX_ReadPageAddr_Data_QUAD((unsigned char *)(Default_BUFF+2048*i),0,i+page,2048); 			
//		}

//		W25NXX_Write_SR(0xB0,W25NXX_ReadSR(0xB0)|0x08);   //NandFlash 都切换到 buffer mode 
//		for(i=0;i<(endpage-page+1);i+=1)
//		{			
//			//------从flash读数据到BUFF-----	
//			CS_FLash_RESET();                            //使能器件   
//			SSI2_ReadWriteByte(0x13);
//			SSI2_ReadWriteByte((i+page)>>16);             
//			SSI2_ReadWriteByte((i+page)>>8);     //发送16bit页地址，将对应页的数据提取到BUFF中     
//			SSI2_ReadWriteByte((i+page));   
//			CS_FLash_SET(); 	
//			W25NXX_Wait_Busy();
//			//------再从BUFF读数据到单片机内-----

//			SPI5.DFS = DFS_32_BIT;      				//数据帧位数格式
//			SPI5.NDF = LEN_TEST-1;
//			SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler_for_NandFlash;
//			SPI5.Address_Length = ADDR_L16;
//			SPI5.WAIT_CYCLES = 8;
//			SPI5_Quad_Read_Init();
//			
//		
//			SSI2_DMA_RX((unsigned char *)(Default_BUFF+2048*i),0x6B,0,LEN_TEST,32,QUAD_mode,0);


////			Check_SSI2_Busy();
//			SPI5_STD_Init(); 								//切回单线
////			W25NXX_Wait_Busy();			
//		}

//		if(start_remain==0)
//		{										
//			SPI5.DFS = DFS_32_BIT;
//			SPI5.NDF = byte_width - 1;
//			SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
//			SPI5.WAIT_CYCLES = 8;     
//			SPI5_Quad_Read_Init();			
//			SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2),0x6B,Addr+X_W*2*i,byte_width,32,QUAD_mode,0);
//			
//			if(end_remain)
//			{				
//				SPI5.DFS = DFS_16_BIT;
//				SPI5.NDF = 1 - 1;
//				SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
//				SPI5.WAIT_CYCLES = 8;     
//				SPI5_Quad_Read_Init();			
//				SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2),0x6B,Addr+X_W*2*(i+1)-2,1,16,QUAD_mode,0);
//			}			
//		}
//		else if(start_remain==1)
//		{				
//			SPI5.DFS = DFS_16_BIT;
//			SPI5.NDF = 1 - 1;
//			SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
//			SPI5.WAIT_CYCLES = 8;     
//			SPI5_Quad_Read_Init();			
//			SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2),0x6B,Addr+X_W*2*i,1,16,QUAD_mode,0);			

//			SPI5.DFS = DFS_32_BIT;
//			SPI5.NDF = byte_width - 1;
//			SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
//			SPI5.WAIT_CYCLES = 8;     
//			SPI5_Quad_Read_Init();			
//			SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+2),0x6B,Addr+X_W*2*i+2,byte_width,32,QUAD_mode,0);
//			
//			if(end_remain)
//			{				
//				SPI5.DFS = DFS_16_BIT;
//				SPI5.NDF = 1 - 1;
//				SPI5.SSI_QUAD_BaudRatePrescaler = SSI2_Quad_BaudRatePrescaler;        
//				SPI5.WAIT_CYCLES = 8;     
//				SPI5_Quad_Read_Init();			
//				SSI2_DMA_RX((unsigned char*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2),0x6B,Addr+X_W*2*(i+1)-2,1,16,QUAD_mode,0);				
//			}			
//		}

//		for (i = 0; i < Y_H; i++)
//		{
////			ReadAddr = Addr+P_W4*2*i;
////			ColumnAddr = ReadAddr%2048;
////			PageAddr = ReadAddr/2048;
////			RemainNum = 2048 - ColumnAddr;
////			if(P_W4*2 <= (2048 - ColumnAddr))	
////			{
////				W25NXX_ReadPageAddr_Data_QUAD((unsigned char *)(lay0+canvas_w*2*(Y1+i)+2*X1),ColumnAddr,PageAddr,P_W4*2);				
////			}
////			else
////			{
////				W25NXX_ReadPageAddr_Data_QUAD((unsigned char *)(lay0+canvas_w*2*(Y1+i)+2*X1),ColumnAddr,PageAddr,RemainNum);
////				W25NXX_ReadPageAddr_Data_QUAD((unsigned char *)(lay0+canvas_w*2*(Y1+i)+2*X1+RemainNum),0,PageAddr+1,P_W4*2-RemainNum);
////			}		
//			
//			W25NXX_Read_NoCheck((unsigned char *)(lay0+canvas_w*2*(Y1+i)+2*X1),Addr+X_W*2*i,X_W*2,4);			
//		}

	}

//	time=GetTickTime();
//	printf("[DMAC_QUAD_SSI_read] Taken %d uS\r\n",time*10);	
}

//void LT768_DMA_24bit_Block_Or_Line_16bpp
//( 
// unsigned char SCS
//,unsigned char Clk
//,unsigned short X1
//,unsigned short Y1
//,unsigned short X_W	
//,unsigned short Y_H
//,unsigned short P_W
//,unsigned int Addr	
//,unsigned int lay0        // 层的地址	
//,unsigned short canvas_w     // 图层宽度
//)
//{
//	u16 i;
//	u32 time;
//	
//	u16 byte_width;
////	u8 byte_remain;
//	
////	byte_width=X_W/2;
////	byte_remain=X_W%2;
//	
//	u8 end_remain;
//	u32 addr_sdram;
//	u8 start_remain;
//	
//	if(X_W==0 || Y_H==0)	return ;
//	
//	addr_sdram=lay0+X1*2;
//	if(addr_sdram%4==0)
//	{
//		start_remain=0;
//		if(X_W%2==0)
//			end_remain=0;
//		else
//			end_remain=1;
//		byte_width=X_W/2;
//	}		
//	else	
//	{
//		start_remain=1;
//		if(X_W%2==0)
//			end_remain=1;
//		else
//			end_remain=0;
//		byte_width=(X_W-1)/2;
//	}

//	SSIHandle.Instance = SSI2;
//	SSIHandle.Init.DFS = DFS_32_BIT;
//	SSIHandle.Init.NDF = byte_width - 1;	//
//	HAL_SSI_Init(&SSIHandle, ssi_timeout);

//	
//	hdma.instance = DMAC2;
////	hdma.init.channel_num = 0;
//	hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
//	hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
////	hdma.init.src_inc = HAL_DMAC_SINC_INC;
//	hdma.init.transfer_size = byte_width;	//
//	
////	InitTickTime();
//	for (i = 0; i < Y_H; i++)
//	{
//		if(start_remain==0)
//		{
//			if(end_remain)
//			{
//				SSIHandle.Instance = SSI2;
////				SSIHandle.Init.DFS = DFS_32_BIT;
//				SSIHandle.Init.NDF = byte_width - 1;	
//				HAL_SSI_Init(&SSIHandle, ssi_timeout);
//				
//				hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
//				hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
//				hdma.init.transfer_size = byte_width;
//			}		
//			DMAC_QUAD_SSI_read(Addr+X_W*2*i,(unsigned int*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2));
//			
//			if(end_remain)
//			{
//				SSIHandle.Instance = SSI2;
//				SSIHandle.Init.NDF = 1 - 1;	//
//				HAL_SSI_Init(&SSIHandle, ssi_timeout);
//				
//				hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//				hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//				hdma.init.transfer_size = 1;	//
//				
//				DMAC_QUAD_SSI_read(Addr+X_W*2*(i+1)-2,(unsigned int*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2));
//			}			
//		}
//		else if(start_remain==1)
//		{
//			SSIHandle.Instance = SSI2;
//			SSIHandle.Init.NDF = 1 - 1;	//
//			HAL_SSI_Init(&SSIHandle, ssi_timeout);
//			
//			hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//			hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//			hdma.init.transfer_size = 1;	//
//			
//			DMAC_QUAD_SSI_read(Addr+X_W*2*i,(unsigned int*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2));
//			
//			SSIHandle.Instance = SSI2;
//			SSIHandle.Init.NDF = byte_width - 1;	
//			HAL_SSI_Init(&SSIHandle, ssi_timeout);
//			
//			hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
//			hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
//			hdma.init.transfer_size = byte_width;
//	
//			DMAC_QUAD_SSI_read(Addr+X_W*2*i+2,(unsigned int*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+2));
//			
//			if(end_remain)
//			{
//				SSIHandle.Instance = SSI2;
//				SSIHandle.Init.NDF = 1 - 1;	//
//				HAL_SSI_Init(&SSIHandle, ssi_timeout);
//				
//				hdma.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//				hdma.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
//				hdma.init.transfer_size = 1;	//
//				
//				DMAC_QUAD_SSI_read(Addr+X_W*2*(i+1)-2,(unsigned int*)(lay0+Lay_Canvas_Width*(i+Y1)*2+X1*2+X_W*2-2));
//			}			
//		}

//	}
////	time=GetTickTime();
////	printf("[DMAC_QUAD_SSI_read] Taken %d uS\r\n",time*10);
//}


//void LT768_DMA_Align_Tran(unsigned int S0_Addr,unsigned short S0_W,unsigned short XS0,unsigned short YS0,unsigned int Des_Addr,unsigned short Des_W,unsigned short XDes,unsigned short YDes,unsigned char start_remain,unsigned char end_remain,unsigned short byte_width,unsigned short line)
//{
void LT768_DMA_Align_Tran(unsigned int S0_Addr,unsigned short S0_W,unsigned short XS0,unsigned short YS0,unsigned int Des_Addr,unsigned short Des_W,unsigned short XDes,unsigned short YDes,unsigned char start_remain,unsigned char end_remain,unsigned short byte_width,unsigned short line)
{	
		if(start_remain==0)
		{
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.transfer_size = byte_width;
			}
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(line+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(line+YS0)*2+XS0*2));
			
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(line+YDes)*2+XDes*2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(line+YS0)*2+XS0*2+byte_width*4));
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}
		else if(start_remain==1)
		{
			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.transfer_size = 1;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(line+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(line+YS0)*2+XS0*2));
			

			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.transfer_size = byte_width;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(line+YDes)*2+XDes*2+2),(unsigned char *)(S0_Addr+S0_W*(line+YS0)*2+XS0*2+2));
			
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(line+YDes)*2+XDes*2+2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(line+YS0)*2+XS0*2+2+byte_width*4));
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}	
}

void LT768_BTE_Memory_Copy
(
 unsigned int S0_Addr     // SO图像的内存起始地址
,unsigned short S0_W       // S0图像的宽度
,unsigned short XS0        // S0图像的左上方X坐标
,unsigned short YS0        // S0图像的左上方Y坐标
,unsigned int S1_Addr     // S1图像的内存起始地址
,unsigned short S1_W       // S1图像的宽度
,unsigned short XS1        // S1图像的左上方X坐标
,unsigned short YS1        // S1图像的左上方Y坐标
,unsigned int Des_Addr    // 目的图像的内存起始地址
,unsigned short Des_W      // 目的图像的宽度
,unsigned short XDes       // 目的图像的左上方X坐标
,unsigned short YDes       // 目的图像的左上方Y坐标
,unsigned int ROP_Code     // 光栅操作模式
,unsigned short X_W       // 活动窗口的宽度
,unsigned short Y_H       // 活动窗口的长度
)
{
    unsigned int i,time;
	
	u16 byte_width;
	u8 end_remain;
	u32 addr_sdram;
	u8 start_remain;
	
	if(X_W==0 || Y_H==0)	return ;
	
	addr_sdram=Des_Addr+XDes*2;
	if(addr_sdram%4==0)
	{
		start_remain=0;
		if(X_W%2==0)
			end_remain=0;
		else
			end_remain=1;
		byte_width=X_W/2;
	}		
	else	
	{
		start_remain=1;
		if(X_W%2==0)
			end_remain=1;
		else
			end_remain=0;
		byte_width=(X_W-1)/2;
	}		
		
	
//	InitTickTime();
	
	hdma2.instance = DMAC1;
//	hdma2.init.channel_num = 0;//HAL_DMACC_CHANNEL_0;
	hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.src_inc = HAL_DMAC_SINC_INC;
	hdma2.init.transfer_size = byte_width;
	
	for(i=0;i<Y_H;i++)
	{
//		LT768_DMA_Align_Tran(S0_Addr,S0_W,XS0,YS0,Des_Addr,Des_W,XDes,YDes,start_remain,end_remain,byte_width,i);
		if(start_remain==0)
		{
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.transfer_size = byte_width;
			}
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2));
			
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2+byte_width*4));
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}
		else if(start_remain==1)
		{
			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.transfer_size = 1;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2));
			

			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.transfer_size = byte_width;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2));
			
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2+byte_width*4));
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}
		
	}

//	time=GetTickTime();
//	printf("[DMA_Demo] Taken %d uS\r\n",time*10);
}

/*  结合 Chroma Key 的内存复制（不含 ROP） */
void LT768_BTE_Memory_Copy_Chroma_key
(
 unsigned long S0_Addr             // SO图像的内存起始地址
,unsigned short S0_W               // S0图像的宽度
,unsigned short XS0                // S0图像的左上方X坐标
,unsigned short YS0                // S0图像的左上方Y坐标
,unsigned long Des_Addr            // 目的图像的内存起始地址
,unsigned short Des_W              // 目的图像的宽度
,unsigned short XDes               // 目的图像的左上方X坐标
,unsigned short YDes               // 目的图像的左上方X坐标
,unsigned long Background_color    // 透明色
,unsigned short X_W                // 活动窗口的宽度
,unsigned short Y_H                // 活动窗口的长度
)
{
#if 1
	unsigned int i,j,time;
//	InitTickTime();
	for(i=0;i<Y_H;i++)
	{
		for(j=0;j<X_W;j++)
		{
			if(*(__IO uint16_t*)(S0_Addr+XS0*2+YS0*S0_W*2+j*2+i*S0_W*2)!=Background_color)
				*(__IO uint16_t*)(Des_Addr+XDes*2+YDes*Des_W*2+j*2+i*Des_W*2) = *(__IO uint16_t *)(S0_Addr+XS0*2+YS0*S0_W*2+j*2+i*S0_W*2);
		}
	 }
//	time=GetTickTime();
//	printf("[DMA_Demo] Taken %d uS\r\n",time*10);
#else
	
    unsigned int i,j,time;
	unsigned int src_addr=0;
	unsigned int dst_addr=0;
	
	u16 byte_width;
	u8 end_remain;
	u32 addr_sdram;
	u8 start_remain;
	
	if(X_W==0 || Y_H==0)	return ;
	
	addr_sdram=Des_Addr+XDes*2;
	if(addr_sdram%4==0)
	{
		start_remain=0;
		if(X_W%2==0)
			end_remain=0;
		else
			end_remain=1;
		byte_width=X_W/2;
	}		
	else	
	{
		start_remain=1;
		if(X_W%2==0)
			end_remain=1;
		else
			end_remain=0;
		byte_width=(X_W-1)/2;
	}		
		
	
//	InitTickTime();
	

	for(i=0;i<Y_H;i++)
	{
		if(start_remain==0)
		{
			for(j=0;j<byte_width;j++)
			{
				src_addr = S0_Addr+XS0*2+YS0*S0_W*2+j*4+i*S0_W*2;
				dst_addr = Des_Addr+XDes*2+YDes*Des_W*2+j*4+i*Des_W*2;
				
				if(*(__IO uint16_t*)(src_addr)!=Background_color && *(__IO uint16_t*)(src_addr+2)!=Background_color)
				{
					*(__IO uint32_t*)(dst_addr) = *(__IO uint32_t *)(src_addr);				
				}
				else if(*(__IO uint16_t*)(src_addr)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr) = *(__IO uint16_t *)(src_addr);
				}
				else if(*(__IO uint16_t*)(src_addr+2)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr+2) = *(__IO uint16_t *)(src_addr+2);
				}
			}
//			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2));
			
			if(end_remain)
			{
				src_addr = S0_Addr+S0_W*(i+YS0)*2+XS0*2+byte_width*4;
				dst_addr = Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4;
				if(*(__IO uint16_t*)(src_addr)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr) = *(__IO uint16_t *)(src_addr);
				}								
//				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2+byte_width*4));
			}			
		}
		else if(start_remain==1)
		{
			src_addr = S0_Addr+S0_W*(i+YS0)*2+XS0*2;
			dst_addr = Des_Addr+Des_W*(i+YDes)*2+XDes*2;
			if(*(__IO uint16_t*)(src_addr)!=Background_color)
			{
				*(__IO uint16_t*)(dst_addr) = *(__IO uint16_t *)(src_addr);
			}			
//			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+XDes*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+XS0*2));
			
			for(j=0;j<byte_width;j++)
			{
				src_addr = S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2+4*j;
				dst_addr = Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2+4*j;
				
				if(*(__IO uint16_t*)(src_addr)!=Background_color && *(__IO uint16_t*)(src_addr+2)!=Background_color)
				{
					*(__IO uint32_t*)(dst_addr) = *(__IO uint32_t *)(src_addr);				
				}
				else if(*(__IO uint16_t*)(src_addr)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr) = *(__IO uint16_t *)(src_addr);
				}
				else if(*(__IO uint16_t*)(src_addr+2)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr+2) = *(__IO uint16_t *)(src_addr+2);
				}
			}			
//			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2));
			
			if(end_remain)
			{
				src_addr = S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2+byte_width*4;
				dst_addr = Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2+byte_width*4;
				if(*(__IO uint16_t*)(src_addr)!=Background_color)
				{
					*(__IO uint16_t*)(dst_addr) = *(__IO uint16_t *)(src_addr);
				}								
//				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Des_W*(i+YDes)*2+(XDes+1)*2+byte_width*4),(unsigned char *)(S0_Addr+S0_W*(i+YS0)*2+(XS0+1)*2+byte_width*4));
			}			
		}	
	}
//	time=GetTickTime();
//	printf("[DMA_Demo] Taken %d uS\r\n",time*10);	
#endif
}

void BTE_Pixel_16bpp_Alpha_Blending																								//16位png图片显示函数
(
 unsigned long S0_Addr         // SO图像的内存起始地址															//用于与png图片合成的背景图
 ,unsigned short S0_W          // S0图像的宽度
 ,unsigned short XS0           // S0图像的左上方X坐标
 ,unsigned short YS0           // S0图像的左上方Y坐标
 ,unsigned long S1_Addr        // S1图像的内存起始地址														 	//png图片存放的地址
 ,unsigned short S1_W          // S1图像的宽度
 ,unsigned short XS1           // S1图像的左上方X坐标
 ,unsigned short YS1           // S1图像的左上方Y坐标
 ,unsigned long Des_Addr       // 目的图像的内存起始地址														//处理后的png图片显示地址
 ,unsigned short Des_W         // 目的图像的宽度
 ,unsigned short XDes          // 目的图像的左上方X坐标
 ,unsigned short YDes          // 目的图像的左上方X坐标
 ,unsigned short X_W           // 活动窗口的宽度
 ,unsigned short Y_H           // 活动窗口的长度
)
{	
	__IO unsigned short i=0,j=0,rcolorpng=0,rcolorbg=0;
	__IO unsigned short R1_val=0,G1_val=0,B1_val=0,A1_val=15;
	__IO unsigned short R0_val=0,G0_val=0,B0_val=0;
	__IO unsigned short R2_val=0,G2_val=0,B2_val=0;
	for(i=0;i<Y_H;i++)
	{
		for(j=0;j<X_W;j++)
		{
			rcolorbg=*(__IO uint16_t *)(S0_Addr+XS0*2+YS0*S0_W*2+j*2+i*S0_W*2);
			rcolorpng=*(__IO uint16_t *)(S1_Addr+XS1*2+YS1*S1_W*2+j*2+i*S1_W*2);
			A1_val = (rcolorpng>>12)&0x0F;
			if(A1_val!=0)
			{
				R1_val = (rcolorpng>>8)&0x0F;
				G1_val = (rcolorpng>>4)&0x0F;
				B1_val = rcolorpng&0x0F;
				
				R0_val = (rcolorbg>>12)&0x0F;
				G0_val = (rcolorbg>>7)&0x0F;
				B0_val = (rcolorbg>>1)&0x0F;
				
				R2_val = ((R1_val * A1_val + R0_val * (15-A1_val))/15)&0x0F;
				G2_val = ((G1_val * A1_val + G0_val * (15-A1_val))/15)&0x0F;
				B2_val = ((B1_val * A1_val + B0_val * (15-A1_val))/15)&0x0F;

				*(__IO uint16_t *)(Des_Addr+XDes*2+YDes*Des_W*2+j*2+i*Des_W*2)=(R2_val<<12)|(G2_val<<7)|(B2_val<<1);
			}
			else
			{
				*(__IO uint16_t *)(Des_Addr+XDes*2+YDes*Des_W*2+j*2+i*Des_W*2)=rcolorbg;
			}
		}
	}
}

/* 结合透明度的内存复制 */
void BTE_Alpha_Blending
(
 unsigned long S0_Addr         // SO图像的内存起始地址
 ,unsigned short S0_W          // S0图像的宽度
 ,unsigned short XS0           // S0图像的左上方X坐标
 ,unsigned short YS0           // S0图像的左上方Y坐标
 ,unsigned long S1_Addr        // S1图像的内存起始地址
 ,unsigned short S1_W          // S1图像的宽度
 ,unsigned short XS1           // S1图像的左上方X坐标
 ,unsigned short YS1           // S1图像的左上方Y坐标
 ,unsigned long Des_Addr       // 目的图像的内存起始地址
 ,unsigned short Des_W         // 目的图像的宽度
 ,unsigned short XDes          // 目的图像的左上方X坐标
 ,unsigned short YDes          // 目的图像的左上方X坐标
 ,unsigned short X_W           // 活动窗口的宽度
 ,unsigned short Y_H           // 活动窗口的长度
 ,unsigned char alpha          // 透明度等级（32等级）
)
{	
	unsigned short i=0,j=0,rcolors0,rcolors1;
	unsigned short R1_val,G1_val,B1_val;
	unsigned short R0_val,G0_val,B0_val;
	unsigned short R2_val,G2_val,B2_val;
	
	if(alpha!=0)
	{
		for(i=0;i<Y_H;i++)
		{
			for(j=0;j<X_W;j++)
			{
				rcolors0=*(__IO uint16_t *)(S0_Addr+XS0*2+YS0*S0_W*2+j*2+i*S0_W*2);
				rcolors1=*(__IO uint16_t *)(S1_Addr+XS1*2+YS1*S1_W*2+j*2+i*S1_W*2);

				R1_val = (rcolors0>>11)&0x1F;
				G1_val = (rcolors0>>5)&0x3F;
				B1_val = rcolors0&0x1F;
				
				R0_val = (rcolors1>>11)&0x1F;
				G0_val = (rcolors1>>5)&0x3F;
				B0_val = rcolors1&0x1F;
				
				R2_val = ((R1_val * (32-alpha) + R0_val * alpha)/32)&0x1F;
				G2_val = ((G1_val * (32-alpha) + G0_val * alpha)/32)&0x3F;
				B2_val = ((B1_val * (32-alpha) + B0_val * alpha)/32)&0x1F;

				*(__IO uint16_t *)(Des_Addr+XDes*2+YDes*Des_W*2+j*2+i*Des_W*2)=(R2_val<<11)|(G2_val<<5)|B2_val;
			}
		}
	}
	else
	{
		LT768_BTE_Memory_Copy(S0_Addr,S0_W,XS0,YS0,
							  S1_Addr,S1_W,XS1,YS1,
							  Des_Addr,Des_W,XDes,YDes,
							  0x0c,X_W,Y_H
							);
	}
}


void LT768_DrawLine(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned long color)
{
	UINT16 t;
	int xerr=0,yerr=0,delta_x,delta_y,distance;
	int incx,incy,uRow,uCol;
	delta_x=x2-x1; //计算坐标增量
	delta_y=y2-y1;
	uRow=x1;
	uCol=y1;
	if(delta_x>0)incx=1; //设置单步方向
	else if(delta_x==0)incx=0;//垂直线
	else {incx=-1;delta_x=-delta_x;}

	if(delta_y>0)incy=1;
	else if(delta_y==0)incy=0;//水平线
	else{incy=-1;delta_y=-delta_y;}

	if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
	else distance=delta_y;
	for(t=0;t<=distance+1;t++ )//画线输出
	{
		writew((Lay_Canvas_Addr+(uCol*Lay_Canvas_Width*2)+(uRow*2)),color);
		xerr+=delta_x ;
		yerr+=delta_y ;
		if(xerr>distance)
		{
			xerr-=distance;
			uRow+=incx;
		}
		if(yerr>distance)
		{
			yerr-=distance;
			uCol+=incy;
		}
	}
}

void LT768_DrawLine_Width
(
 unsigned short X1        // X1坐标
,unsigned short Y1        // Y1坐标
,unsigned short X2        // X2坐标
,unsigned short Y2        // Y2坐标
,unsigned long  LineColor // 线段颜色
,unsigned short Width     // 线段宽度
)
{
	unsigned short  i = 0;
	signed  short x = 0, y = 0;
	double temp = 0;
	x = X2 - X1;
	y = Y2 - Y1;
	if(x == 0) temp = 2;
	else temp = -((double)y/(double)x);
	if(temp>=-1&&temp<=1)
	{
			while(Width--)
		{
			LT768_DrawLine(X1,Y1+i,X2,Y2+i,LineColor);
			LT768_DrawLine(X1,Y1-i,X2,Y2-i,LineColor);
			i++;
		}	
	}
		
	else 
	{
			while(Width--)
		{
			LT768_DrawLine(X1+i,Y1,X2+i,Y2,LineColor);
			LT768_DrawLine(X1-i,Y1,X2-i,Y2,LineColor);
			i++;
		}	
	}
}

void LT768_FillColor(UINT16 x,UINT16 y,UINT16 w,UINT16 h,UINT16 color)
{
	UINT16 i,j;
	for(i=0;i<h;i++)
	{
		for(j=0;j<w;j++)
			writew((Lay_Canvas_Addr+(x*2)+(y*Lay_Canvas_Width*2)+(j*2)+(i*Lay_Canvas_Width*2)),color);
	}
}
void LT768_Draw_hline(UINT16 x0,UINT16 y0,UINT16 len,UINT16 color)
{
	if((len==0)||(x0>LCD_XSIZE_TFT-1)||(y0>LCD_YSIZE_TFT-1))return;
	LT768_FillColor(x0,y0,len,1,color);
}
void LT768_Draw_vline(UINT16 x0,UINT16 y0,UINT16 len,UINT16 color)
{
	if((len==0)||(x0>LCD_XSIZE_TFT-1)||(y0>LCD_YSIZE_TFT-1))return;
	LT768_FillColor(x0,y0,1,len,color);
}
void _draw_circle_8(int xc, int yc, int x, int y, UINT16 color)
{
	writew((Lay_Canvas_Addr+((xc + x))*2)+((yc + y))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc - x))*2)+((yc + y))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc + x))*2)+((yc - y))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc - x))*2)+((yc - y))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc + y))*2)+((yc + x))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc - y))*2)+((yc + x))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc + y))*2)+((yc - x))*Lay_Canvas_Width*2,color);
	writew((Lay_Canvas_Addr+((xc - y))*2)+((yc - x))*Lay_Canvas_Width*2,color);
}
void LT768_DrawPoint(UINT16 x,UINT16 y,UINT16 color)
{
	writew((Lay_Canvas_Addr+(y*Lay_Canvas_Width*2)+(x*2)),color);
}
void LT768_Draw_expoint(UINT16 sx,UINT16 sy,UINT16 ex,UINT16 ey,UINT16 x,UINT16 y,UINT16 color)
{
	if(x<=ex&&x>=sx&&y<=ey&&y>=sy)
	{
		LT768_DrawPoint(x,y,color);
	}
}
//画8点(Bresenham算法)
//(sx,sy),(ex,ey):设定的显示范围
//(rx,ry,a,b):参数
//color:颜色
void gui_draw_circle8(UINT16 sx,UINT16 sy,UINT16 ex,UINT16 ey,UINT16 rx,UINT16 ry,int a,int b,UINT16 color)
{
	LT768_Draw_expoint(sx,sy,ex,ey,rx+a,ry-b,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx+b,ry-a,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx+b,ry+a,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx+a,ry+b,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx-a,ry+b,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx-b,ry+a,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx-b,ry-a,color);
	LT768_Draw_expoint(sx,sy,ex,ey,rx-a,ry-b,color);
}
void gui_draw_arc(UINT16 sx,UINT16 sy,UINT16 ex,UINT16 ey,UINT16 rx,UINT16 ry,UINT16 r,UINT16 color,UINT8 mode)
{
	int a,b,c;
	int di;
	a=0;b=r;
	di=3-(r<<1);	//判断下个点位置的标志
	while(a<=b)
	{
		if(mode)for(c=a;c<=b;c++)gui_draw_circle8(sx,sy,ex,ey,rx,ry,a,c,color);//画实心圆
 		else gui_draw_circle8(sx,sy,ex,ey,rx,ry,a,b,color);					   //画空心圆
		a++;
		//使用Bresenham算法画圆
		if(di<0)di +=4*a+6;
		else
		{
			di+=10+4*(a-b);
			b--;
		}
	}
}
void LT768_DrawCircle(unsigned short xc,unsigned short yc,unsigned short r,unsigned long color)
{
	int x = 0, y = r, d;
	d = 3 - 2 * r;

	while (x <= y) {
		_draw_circle_8(xc, yc, x, y, color);
		if (d < 0) {
			d = d + 4 * x + 6;
		} else {
			d = d + 4 * (x - y) + 10;
			y--;
		}
		x++;
	}
}
void LT768_DrawCircle_Fill(unsigned short xc,unsigned short yc,unsigned short r,unsigned long color)
{
	UINT32 i;
	UINT32 imax = ((UINT32)r*707)/1000+1;
	UINT32 sqmax = (UINT32)r*(UINT32)r+(UINT32)r/2;
	UINT32 x=r;
	LT768_Draw_hline(xc-r,yc,2*r,color);
	for (i=1;i<=imax;i++)
	{
		if ((i*i+x*x)>sqmax)
		{
			// draw lines from outside
			if (x>imax)
			{
				LT768_Draw_hline (xc-i+1,yc+x,2*(i-1),color);
				LT768_Draw_hline (xc-i+1,yc-x,2*(i-1),color);
			}
			x--;
		}
		// draw lines from inside (center)
		LT768_Draw_hline(xc-x,yc+i,2*x,color);
		LT768_Draw_hline(xc-x,yc-i,2*x,color);
	}
}
void LT768_DrawCircle_Width(unsigned short xc, unsigned short yc, unsigned short r,unsigned long WidthColor,unsigned long BackgroundColor,unsigned short Width)
{
	LT768_DrawCircle_Fill(xc,yc,r+Width,WidthColor);
	LT768_DrawCircle_Fill(xc,yc,r,BackgroundColor);
}
void LT768_DrawEllipse(unsigned short x0,unsigned short y0,unsigned short rx,unsigned short ry,unsigned long color)
{
	UINT32 OutConst, Sum, SumY;
	UINT16 x,y;
	UINT16 xOld;
	UINT32 _rx = rx;
	UINT32 _ry = ry;
	if(rx>x0||ry>y0)return;//非法.
	OutConst = _rx*_rx*_ry*_ry+(_rx*_rx*_ry>>1);  // Constant as explaint above
	// To compensate for rounding
	xOld = x = rx;
	for (y=0; y<=ry; y++)
	{
		if (y==ry)x=0;
		else
		{
			SumY =((UINT32)(rx*rx))*((UINT32)(y*y)); // Does not change in loop
			while(Sum = SumY + ((UINT32)(ry*ry))*((UINT32)(x*x)),(x>0) && (Sum>OutConst)) x--;
		}
		// Since we draw lines, we can not draw on the first iteration
		if (y)
		{
			LT768_DrawLine(x0-xOld,y0-y+1,x0-x,y0-y,color);
			LT768_DrawLine(x0-xOld,y0+y-1,x0-x,y0+y,color);
			LT768_DrawLine(x0+xOld,y0-y+1,x0+x,y0-y,color);
			LT768_DrawLine(x0+xOld,y0+y-1,x0+x,y0+y,color);
		}
		xOld = x;
	}
}
void LT768_DrawEllipse_Fill(unsigned short x0,unsigned short y0,unsigned short rx,unsigned short ry,unsigned long color)
{
	UINT32 OutConst, Sum, SumY;
	UINT16 x,y;
	UINT32 _rx = rx;
	UINT32 _ry = ry;
	OutConst = _rx*_rx*_ry*_ry+(_rx*_rx*_ry>>1);  // Constant as explaint above
	// To compensate for rounding
	x = rx;
	for (y=0; y<=ry; y++)
	{
		SumY =((UINT32)(rx*rx))*((UINT32)(y*y)); // Does not change in loop
		while (Sum = SumY + ((UINT32)(ry*ry))*((UINT32)(x*x)),(x>0) && (Sum>OutConst))x--;
		LT768_Draw_hline(x0-x,y0+y,2*x,color);
		if(y)LT768_Draw_hline(x0-x,y0-y,2*x,color);
	}
}
void LT768_DrawEllipse_Width(unsigned short x0, unsigned short y0, unsigned short rx,unsigned short ry,unsigned long WidthColor,unsigned long BackgroundColor,unsigned short Width)
{
	LT768_DrawEllipse_Fill(x0,y0,rx+Width,ry+Width,WidthColor);
	LT768_DrawEllipse_Fill(x0,y0,rx,ry,BackgroundColor);
}


void LT768_DrawSquare(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned long color)
{
	LT768_DrawLine(x1,y1,x2,y1,color);
	LT768_DrawLine(x1,y1,x1,y2,color);
	LT768_DrawLine(x1,y2,x2,y2,color);
	LT768_DrawLine(x2,y1,x2,y2,color);
}

void LT768_DrawSquare_Fill
(
 unsigned short X1                // X1位置
,unsigned short Y1                // Y1位置
,unsigned short X2                // X2位置
,unsigned short Y2                // Y2位置
,unsigned int ForegroundColor    // 背景颜色
)
{
    unsigned int i,time;
	
	u16 byte_width;
	u8 end_remain;
	u32 addr_sdram;
	u8 start_remain;
	u32 Color_4bytes = (ForegroundColor<<16)+ForegroundColor;
	u16 Color_2bytes = ForegroundColor;
	u32 Des_Addr = Lay_Canvas_Addr;
	u16 temp;
	
//	if(X1==X2)	return ;
	if(X1>X2)	{temp=X1;X1=X2;X2=temp;}
	if(Y1>Y2)	{temp=Y1;Y1=Y2;Y2=temp;}
	
	
	u16 Width_W = (X2-X1+1);
	
	addr_sdram=Des_Addr+X1*2;
	if(addr_sdram%4==0)
	{
		start_remain=0;
		if(Width_W%2==0)
			end_remain=0;
		else
			end_remain=1;
		byte_width=Width_W/2;
	}		
	else	
	{
		start_remain=1;
		if(Width_W%2==0)
			end_remain=1;
		else
			end_remain=0;
		byte_width=(Width_W-1)/2;
	}
	
//	InitTickTime();
	
	hdma2.instance = DMAC1;
//	hdma2.init.channel_num = 0;//HAL_DMACC_CHANNEL_0;
	hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
	hdma2.init.src_inc = HAL_DMAC_SINC_NO_CHANGE;
	hdma2.init.transfer_size = byte_width;
	for(i=0;i<(Y2-Y1+1);i++)
	{
		if(start_remain==0)
		{
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
				hdma2.init.transfer_size = byte_width;
			}
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Lay_Canvas_Width*(i+Y1)*2+X1*2),(unsigned char *)&Color_4bytes);
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Lay_Canvas_Width*(i+Y1)*2+X1*2+byte_width*4),(unsigned char *)&Color_2bytes);
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}
		else if(start_remain==1)
		{
			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
			hdma2.init.transfer_size = 1;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Lay_Canvas_Width*(i+Y1)*2+X1*2),(unsigned char *)&Color_2bytes);
			

			hdma2.instance = DMAC1;
			hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_32BITS;
			hdma2.init.transfer_size = byte_width;
			DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Lay_Canvas_Width*(i+Y1)*2+(X1+1)*2),(unsigned char *)&Color_4bytes);
			
//			printf("ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2));
			
			if(end_remain)
			{
				hdma2.instance = DMAC1;
				hdma2.init.dst_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.src_tr_width = HAL_DMAC_TR_WIDTH_16BITS;
				hdma2.init.transfer_size = 1;
				DMAC_M2MTest2(DMAC1,0,byte_width,(unsigned char *)(Des_Addr+Lay_Canvas_Width*(i+Y1)*2+(X1+1)*2+byte_width*4),(unsigned char *)&Color_2bytes);
//				printf("remain_ADDR:%#x\r\n",(Des_Addr+Des_W*(i+YDes)*2+XDes*2+byte_width*4));
			}			
		}
	}	
//	time=GetTickTime();
//	printf("[Color_Demo] Taken %d uS\r\n",time*10);
}

void LT768_DrawSquare_Width
(
 unsigned short X1                // X1位置
,unsigned short Y1                // Y1位置
,unsigned short X2                // X2位置
,unsigned short Y2                // Y2位置
,unsigned long SquareColor        // 画线颜色
,unsigned long ForegroundColor    // 背景颜色
,unsigned short Width             // 线宽
)
{
	LT768_DrawSquare_Fill(X1-Width,Y1-Width,X2+Width,Y2+Width,SquareColor);
	LT768_DrawSquare_Fill(X1,Y1,X2,Y2,ForegroundColor);
}


void LT768_DrawCircleSquare(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short r,unsigned short r2,unsigned long color)
{
	UINT16 temp;
	UINT16 btnxh=0;
	UINT16 width,height;

	if(y1>y2)
	{
		temp=y1;
		y1=y2;
		y2=temp;
	}
	if(x1>x2)
	{
		temp=x1;
		x1=x2;
		x2=temp;
	}

	width=x2-x1+1;
	height=y2-y1+1;

	if(height%2)btnxh=height+1;//基偶数处理
	else btnxh=height;

	LT768_Draw_hline(x1+r,y1,width-2*r,color);					//上
	LT768_Draw_hline(x1+r,y1+btnxh-1,width-2*r,color);			//下
	LT768_Draw_vline(x1,y1+r,btnxh/2-r,color);					//左上
	LT768_Draw_vline(x1,y1+btnxh/2,btnxh/2-r,color);			//左下
	LT768_Draw_vline(x2,y1+r,btnxh/2-r,color);			//右上
	LT768_Draw_vline(x2,y1+btnxh/2,btnxh/2-r,color);	//右下

	gui_draw_arc(x1,y1,x1+r,y1+r,x1+r,y1+r,r,color,0);//左上
	gui_draw_arc(x1,y1+btnxh-r,x1+r,y1+btnxh-1,x1+r,y1+btnxh-r-1,r,color,0);//左下
	gui_draw_arc(x1+width-r,y1,x1+width,y1+r,x1+width-r-1,y1+r,r,color,0);	 //右上
	gui_draw_arc(x1+width-r,y1+btnxh-r,x1+width,y1+btnxh-1,x1+width-r-1,y1+btnxh-r-1,r,color,0);//右下
}

void LT768_DrawCircleSquare_Fill(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short r,unsigned short r2,unsigned long color)
{
	UINT16 temp;
	UINT16 btnxh=0;
	UINT16 width,height;

	if(y1>y2)
	{
		temp=y1;
		y1=y2;
		y2=temp;
	}
	if(x1>x2)
	{
		temp=x1;
		x1=x2;
		x2=temp;
	}

	width=x2-x1+1;
	height=y2-y1+1;

	if(height%2)btnxh=height+1;//基偶数处理
	else btnxh=height;

	LT768_FillColor(x1+r,y1,width-2*r,btnxh/2,color);			//中上
	LT768_FillColor(x1+r,y1+btnxh/2,width-2*r,btnxh/2,color);	//中下
	LT768_FillColor(x1,y1+r,r,btnxh/2-r,color);					//左上
	LT768_FillColor(x1,y1+btnxh/2,r,btnxh/2-r,color);			//左下
	LT768_FillColor(x1+width-r,y1+r,r,btnxh/2-r,color);			//右上
	LT768_FillColor(x1+width-r,y1+btnxh/2,r,btnxh/2-r,color);	//右下

	gui_draw_arc(x1,y1,x1+r,y1+r,x1+r,y1+r,r,color,1);//左上
	gui_draw_arc(x1,y1+btnxh-r,x1+r,y1+btnxh-1,x1+r,y1+btnxh-r-1,r,color,1);//左下
	gui_draw_arc(x1+width-r,y1,x1+width,y1+r,x1+width-r-1,y1+r,r,color,1);	 //右上
	gui_draw_arc(x1+width-r,y1+btnxh-r,x1+width,y1+btnxh-1,x1+width-r-1,y1+btnxh-r-1,r,color,1);//右下
}

void LT768_DrawCircleSquare_Width(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short r,unsigned short r2,unsigned long WidthColor,unsigned long BackgroundColor,unsigned short Width)
{
	UINT16 temp;
	if(y1>y2)
	{
		temp=y1;
		y1=y2;
		y2=temp;
	}
	if(x1>x2)
	{
		temp=x1;
		x1=x2;
		x2=temp;
	}
	LT768_DrawCircleSquare_Fill(x1-Width,y1-Width,x2+Width,y2+Width,r,r,WidthColor);
	LT768_DrawCircleSquare_Fill(x1,y1,x2,y2,r,r,BackgroundColor);
}

void LT768_DrawTriangle(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short x3,unsigned short y3,unsigned long color)
{
	LT768_DrawLine(x1,y1,x2,y2,color);
	LT768_DrawLine(x1,y1,x3,y3,color);
	LT768_DrawLine(x2,y2,x3,y3,color);
}
//void LT768_DrawTriangle_Fill(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short x3,unsigned short y3,unsigned long color)
//{
//	UINT16 t;
//	int xerr=0,yerr=0,delta_x,delta_y,distance;
//	int incx,incy,uRow,uCol;

//	UINT16 temp;
//	if(y1>y2)
//	{
//		temp=y2;
//		y2=y1;
//		y1=temp;
//		temp=x2;
//		x2=x1;
//		x1=temp;
//	}
//	if(y1>y3)
//	{
//		temp=y3;
//		y3=y1;
//		y1=temp;
//		temp=x3;
//		x3=x1;
//		x1=temp;
//	}
//	if(x2>x3)
//	{
//		temp=x3;
//		x3=x2;
//		x2=temp;
//		temp=y3;
//		y3=y2;
//		y2=temp;
//	}

//	delta_x=x3-x2; //计算坐标增量
//	delta_y=y3-y2;
//	uRow=x2;
//	uCol=y2;
//	if(delta_x>0)incx=1; //设置单步方向
//	else if(delta_x==0)incx=0;//垂直线
//	else
//	{
//		incx=-1;delta_x=-delta_x;
//	}

//	if(delta_y>0)incy=1;
//	else if(delta_y==0)incy=0;//水平线
//	else
//	{
//		incy=-1;delta_y=-delta_y;
//	}

//	if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
//	else distance=delta_y;
//	for(t=0;t<=distance+1;t++ )//画线输出
//	{
//		LT768_DrawPoint(uRow,uCol,color);//画点
//		LT768_DrawLine(x1,y1,uRow,uCol,color);
//		xerr+=delta_x ;
//		yerr+=delta_y ;
//		if(xerr>distance)
//		{
//			xerr-=distance;
//			uRow+=incx;
//		}
//		if(yerr>distance)
//		{
//			yerr-=distance;
//			uCol+=incy;
//		}
//	}
//}
void LT768_DrawTriangle_Frame(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short x3,unsigned short y3,unsigned long WidthColor,unsigned long BackgroundColor)
{
	LT768_DrawTriangle_Fill(x1,y1,x2,y2,x3,y3,BackgroundColor);
	LT768_DrawTriangle(x1,y1,x2,y2,x3,y3,WidthColor);
}


void LT768_DrawQuadrilateral
(
 unsigned short X1              // X1位置
,unsigned short Y1              // Y1位置
,unsigned short X2              // X2位置
,unsigned short Y2              // Y2位置
,unsigned short X3              // X3位置
,unsigned short Y3              // Y3位置
,unsigned short X4              // X4位置
,unsigned short Y4              // Y4位置
,unsigned long ForegroundColor  // 画线颜色
)
{
	u8 i=0,j=0;
	u16 temp=0;
	u16 x_min,y_min;
	u16 x[4],y[4];
	u16 x_1[4],y_1[4];
	float k[3];
	float k_max=0;
	float k_min=0;
	u8 num_max=0;
	u8 num_min=0;
	u8 num_mid=0;
	
	x[0] = X1;	y[0] = Y1;
	x[1] = X2;	y[1] = Y2;
	x[2] = X3;	y[2] = Y3;
	x[3] = X4;	y[3] = Y4;

	x_min = x[0];
	y_min = y[0];	
	for(i=1;i<=3;i++)
	{
		if(x[i]<=x_min)	
		{
			x_1[i] = x_min;
			y_1[i] = y_min;

			x_min=x[i];
			y_min=y[i];
		}
		else
		{
			x_1[i] = x[i];
			y_1[i] = y[i];
		}
	}
	x_1[0] = x_min;
	y_1[0] = y_min;
	
	for(i=1;i<=3;i++)
	{
		if(x_1[0]==x_1[i])
		{
			if(y_1[i]<y_1[0])	k[i-1] =  10000.0;
			else if(y_1[i]>y_1[0])	k[i-1] =  -10000.0;
		}
		else
		{
			k[i-1] =  1.0*(y_1[0]-y_1[i])/(x_1[i]-x_1[0]);
		}
	}

	k_max= k[0];
	k_min= k[0];
	num_max = 1;
	num_min = 1;
	for(i=1;i<=2;i++)
	{
		if(k[i]>k_max)
		{
			k_max = k[i];
			num_max = i+1;
		}
		if(k[i]<k_min)
		{
			k_min = k[i];
			num_min = i+1;
		}
	}	
	
	for(i=1;i<=3;i++)
	{
		if(i!=num_max && i!=num_min)	
		{
			num_mid = i;
			break;			
		}
	}	
	LT768_DrawLine(x_1[0],y_1[0],x_1[num_max],y_1[num_max],ForegroundColor); 
	LT768_DrawLine(x_1[0],y_1[0],x_1[num_min],y_1[num_min],ForegroundColor);
	LT768_DrawLine(x_1[num_mid],y_1[num_mid],x_1[num_max],y_1[num_max],ForegroundColor); 
	LT768_DrawLine(x_1[num_mid],y_1[num_mid],x_1[num_min],y_1[num_min],ForegroundColor);
}

void LT768_DrawQuadrilateral_Fill
(
 unsigned short X1              // X1位置
,unsigned short Y1              // Y1位置
,unsigned short X2              // X2位置
,unsigned short Y2              // Y2位置
,unsigned short X3              // X3位置
,unsigned short Y3              // Y3位置
,unsigned short X4              // X4位置
,unsigned short Y4              // Y4位置
,unsigned long ForegroundColor  // 画线颜色
)
{
	
	u8 i=0,j=0;
	u16 temp=0;
	u16 x_min,y_min;
	u16 x[4],y[4];
	u16 x_1[4],y_1[4];
	float k[3];
	float k_max=0;
	float k_min=0;
	u8 num_max=0;
	u8 num_min=0;
	u8 num_mid=0;
	
	x[0] = X1;	y[0] = Y1;
	x[1] = X2;	y[1] = Y2;
	x[2] = X3;	y[2] = Y3;
	x[3] = X4;	y[3] = Y4;

	x_min = x[0];
	y_min = y[0];	
	for(i=1;i<=3;i++)
	{
		if(x[i]<=x_min)	
		{
			x_1[i] = x_min;
			y_1[i] = y_min;

			x_min=x[i];
			y_min=y[i];
		}
		else
		{
			x_1[i] = x[i];
			y_1[i] = y[i];
		}
	}
	x_1[0] = x_min;
	y_1[0] = y_min;
	
	for(i=1;i<=3;i++)
	{
		if(x_1[0]==x_1[i])
		{
			if(y_1[i]<y_1[0])	k[i-1] =  10000.0;
			else if(y_1[i]>y_1[0])	k[i-1] =  -10000.0;
		}
		else
		{
			k[i-1] =  1.0*(y_1[0]-y_1[i])/(x_1[i]-x_1[0]);
		}
	}

	k_max= k[0];
	k_min= k[0];
	num_max = 1;
	num_min = 1;
	for(i=1;i<=2;i++)
	{
		if(k[i]>k_max)
		{
			k_max = k[i];
			num_max = i+1;
		}
		if(k[i]<k_min)
		{
			k_min = k[i];
			num_min = i+1;
		}
	}	
	
	for(i=1;i<=3;i++)
	{
		if(i!=num_max && i!=num_min)	
		{
			num_mid = i;
			break;			
		}
	}
	LT768_DrawTriangle_Fill(x_1[0],y_1[0],x_1[num_max],y_1[num_max],x_1[num_mid],y_1[num_mid],ForegroundColor);
	LT768_DrawTriangle_Fill(x_1[0],y_1[0],x_1[num_min],y_1[num_min],x_1[num_mid],y_1[num_mid],ForegroundColor);
}

//void LT768_DrawQuadrilateral_Fill
//(
// unsigned short X1              // X1位置
//,unsigned short Y1              // Y1位置
//,unsigned short X2              // X2位置
//,unsigned short Y2              // Y2位置
//,unsigned short X3              // X3位置
//,unsigned short Y3              // Y3位置
//,unsigned short X4              // X4位置
//,unsigned short Y4              // Y4位置
//,unsigned long ForegroundColor  // 画线颜色
//)
//{
////	u8 i=0;
////	u8 temp=0;
////	u16 x_min,y_min;
////	u16 x[4],y[4];
////	u16 x_1[4],y_1[4];
////	float 
////	
////	x[0] = X1;	y[0] = Y1;
////	x[1] = X2;	y[1] = Y2;
////	x[2] = X3;	y[2] = Y3;
////	x[3] = X4;	y[3] = Y4;

////	x_min = x[0];
////	y_min = y[0];	
////	for(i=1;i<=3;i++)
////	{
////		if(x[i]<=x_min)	
////		{
////			x_min=x[i];
////			y_min=y[i];
////			
////			x_1[i] = x_min;
////			y_1[i] = y_min;
////		}
////		else
////		{
////			x_1[i] = x[i];
////			y_1[i] = y[i];
////		}
////	}
////	x_1[0] = x_min;
////	y_1[0] = y_min;

//	
//	
//	LT768_DrawTriangle_Fill(X1,Y1,X2,Y2,X3,Y3,ForegroundColor);
//	
//	LT768_DrawTriangle_Fill(X1,Y1,X4,Y4,X3,Y3,ForegroundColor);
//}

void LT768_DrawQuadrangular1
(
 unsigned short X1                 // 顶面左下觇 X 位置
,unsigned short Y1                 // 顶面左下觇 Y 位置
,unsigned short X2                 // 顶面左上觇 X 位置
,unsigned short Y2                 // 顶面左上觇 Y 位置
,unsigned short Width                  // 宽度
,unsigned short High                  // 高度
,unsigned long QuadrangularColor   // 外框颜色
,unsigned long ForegroundColor     // 前景颜色
,unsigned char Wid
)
{
//	printf("\r\nx1:%d y1:%d\r\nx2:%d y2:%d\r\nW:%d H:%d\r\n",X1,Y1,X2,Y2,Width,High);
	LT768_DrawSquare_Fill(X1,Y1,X1+Width,Y1+High,ForegroundColor);
	LT768_DrawQuadrilateral_Fill(X1,Y1,X2,Y2,X2+Width,Y2,X1+Width,Y1,ForegroundColor);
	LT768_DrawQuadrilateral_Fill(X1+Width,Y1,X2+Width,Y2,X2+Width,Y2+High,X1+Width,Y1+High,ForegroundColor);
	
	LT768_DrawSquare(X1,Y1,X1+Width,Y1+High,QuadrangularColor);
	LT768_DrawQuadrilateral(X1,Y1,X2,Y2,X2+Width,Y2,X1+Width,Y1,QuadrangularColor);
	LT768_DrawQuadrilateral(X1+Width,Y1,X2+Width,Y2,X2+Width,Y2+High,X1+Width,Y1+High,QuadrangularColor);
	
	//LT768_DrawSquare_Width(X1,Y1,X1+W,Y1+H,QuadrangularColor,ForegroundColor,Width);
//	LT768_DrawQuadrilateral_Fill(X1-Width,Y1-Width,X2-Width,Y2-2 * Width,X2+W+Width,Y2-2 * Width,X1+W+Width,Y1-Width,QuadrangularColor);
//	LT768_DrawQuadrilateral_Fill(X1,Y1-Width,X2,Y2-Width,X2+W,Y2-Width,X1+W,Y1-Width,ForegroundColor);
//	LT768_DrawQuadrilateral_Fill(X1+W,Y1,X2+W,Y2,X2+W,Y2+H,X1+W,Y1+H,ForegroundColor);
//	
//	LT768_DrawLine_Width(X1,Y1,X2,Y2,QuadrangularColor,Width);
}

UINT8 LT768_DrawCylinder(unsigned short XCenter,unsigned short YCenter,unsigned short X_R,unsigned short Y_R,unsigned short High,unsigned long CylinderColor,unsigned long ForegroundColor,unsigned char Width)
{
	UINT8 cut = 0;
	if(YCenter < High)	return 1;
	//底面椭圆
	LT768_DrawEllipse_Width(XCenter,YCenter,X_R,Y_R,CylinderColor,ForegroundColor,Width);

	//中间矩形
	LT768_DrawSquare_Fill(XCenter-X_R,YCenter-High,XCenter+X_R,YCenter,ForegroundColor);

	//顶面椭圆
	LT768_DrawEllipse_Width(XCenter,YCenter-High,X_R,Y_R,CylinderColor,ForegroundColor,Width);

	if(Width >= 1)
	{
		cut = 1;
		LT768_DrawSquare_Fill(XCenter+X_R+cut,YCenter-High,XCenter+X_R+Width,YCenter,CylinderColor);
		LT768_DrawSquare_Fill(XCenter-X_R-Width,YCenter-High,XCenter-X_R-cut,YCenter,CylinderColor);
	}
	return 0;
}

void LT768_MakeTable(unsigned short X1,unsigned short Y1,unsigned short W0,unsigned short H0,unsigned short L0,unsigned short R0,unsigned long TableColor,unsigned long ItemColor,unsigned long ForegroundColor,unsigned short width1,unsigned short width2,unsigned char mode0)
{
	UINT16 i = 0;
	UINT16 x2,y2;
	x2 = X1 + W0 * R0;
	y2 = Y1 + H0 * L0;

	LT768_DrawSquare_Width(X1,Y1,x2,y2,TableColor,ForegroundColor,width2);

	if(mode0 == 0)	      LT768_DrawSquare_Fill(X1,Y1,X1+W0,y2,ItemColor);
	else if(mode0 == 1)	LT768_DrawSquare_Fill(X1,Y1,x2,Y1+H0,ItemColor);

	for(i = 0 ; i < L0 ; i++)
	{
		LT768_DrawLine_Width(X1,Y1+i*H0,x2,Y1+i*H0,TableColor,width1);
	}

	for(i = 0 ; i < R0 ; i++)
	{
		LT768_DrawLine_Width(X1+i*W0,Y1,X1+i*W0,y2,TableColor,width1);
	}
}

/* 显示外部及内部集成字体 */
void LT768_Print_Outside_Font_String
(
 unsigned short x               // 字体开始显示的x位置
,unsigned short y               // 字体开始显示的y位置
,unsigned long FontColor        // 字体的颜色
,unsigned long BackGroundColor  // 字体的背景色（注意：当字体背景初始化成透明时，设置该值无效）
,unsigned short String_Length		//字符串长度
,unsigned char *c               // 数据缓冲的首地址
)
{

}

/*显示内部_ASCII编码*/
//x,y:起始坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FontColor:字体颜色
//BackGroundColor:背景颜色
//num:字符
void LT768_TFT_Show_Internal_Char(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT16 FontColor,UINT16 BackGroundColor,UINT8 num)
{
	UINT8 temp,t1,t;
	UINT16 y0=y;
	UINT16 ii,jj;
	UINT8 csize=(size/8+((size%8)?1:0))*(size/2);		//得到字体一个字符对应点阵集所占的字节数
//	printf("csize==%d \r\n",csize);
 	num=num-' ';//得到偏移后的值（ASCII字库是从空格开始取模，所以-' '就是对应字符的字库）
	
	t=0;

	if(size==32)
	{
		for(t=0;t<csize;t++)
		{
				for(jj=0;jj<size;jj++)
				{
					temp=asc2_3216[num][t++];	
					for(ii=0;ii<8;ii++)
					{
						if(temp&0x80)LT768_DrawPoint(x+ii,y+jj,FontColor);
						else if(mode==0)LT768_DrawPoint(x+ii,y+jj,BackGroundColor);
						
						temp<<=1;		
					}
					
					temp=asc2_3216[num][t++];	
					for(ii=8;ii<16;ii++)
					{
						if(temp&0x80)LT768_DrawPoint(x+ii,y+jj,FontColor);
						else if(mode==0)LT768_DrawPoint(x+ii,y+jj,BackGroundColor);
				
						temp<<=1;		
					}
				}
		}
	}
	else if(size==16||size==24)
	{
		for(t=0;t<csize;t++)
		{
			if(size==16)  temp=asc2_1608[num][t];	//调用1608字体	
			else if(size==24) temp=asc2_2412[num][t];	//调用2412字体
	//		else if(size==32) temp=asc2_3216[num][t];	//调用2412字体
	//		else return;								//没有的字库	
			
			for(t1=0;t1<8;t1++)
			{
				if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
				else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
				
				temp<<=1;	
				y++;
				if(y>=LCD_YSIZE_TFT)return;		//超区域了
				if((y-y0)==size)
				{
					y=y0;
					x++;
					if(x>=LCD_XSIZE_TFT)return;	//超区域了
					break;
				}
			}
		}
	}
	else return;								//没有的字库
}

//显示Ascll字符串
//x,y :汉字的坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//str:字符串
void LT768_TFT_ShowAscii(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *str)
{
//	UINT8 x0=x;
    while((*str<='~')&&(*str>=' '))//判断是不是非法字符!
    {
        if(x+size/2>LCD_XSIZE_TFT){x=0;y+=size;}
        if(y+size>LCD_YSIZE_TFT)break;//退出
        LT768_TFT_Show_Internal_Char(x,y,size,mode,FontColor,BackGroundColor,*str);
//        LCD_ShowChar(x,y,*p,size,0);
        x+=size/2;
        str++;
    }
}

/*中文字库编码寻址*/
//code 字符串的开始地址,GBK码
//mat  数据存放地址 (size/8+((size%8)?1:0))*(size) bytes大小
//size:字体大小
//FlashAddr:字库地址
void LT768_TFT_Get_HzMat(unsigned char *code,unsigned char *mat,UINT16 csize,UINT32 FlashAddr)
{
	u16 j=0;
	unsigned char qh,ql;
//	unsigned char i;
	unsigned long foffset;
//	UINT8 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	qh=*code;
	ql=*(++code);
//	if(qh<0xA1||ql<0xA1||ql==0xff||qh==0xff)//非 常用汉字
//	{
//	    for(i=0;i<csize;i++)*mat++=0x00;//填充满格
//	    return; //结束访问
//	}
//	if(ql<0x7f)ql-=0x40;//注意!
//	else ql-=0x41;
	ql-=0xA1;
	qh-=0xA1;

	foffset=((unsigned long)94*qh+ql)*csize;	//得到字库中的字节偏移量

	LT_ReadFlash(mat,foffset+FlashAddr,csize);
	
//	if(qh==0xC0-0xA1 && ql==0xD6-0xA1)
//	{
//		for(j=0;j<648;j++)
//		{
//			printf("va[%d]=%x ",j,mat[j]);
//			if(j%12==0)	printf("\r\n");		
//		}
//	}
	
//	switch(size)
//	{
//		case 12:
//			LT268_W25QXX_Read(mat,foffset+FlashAddr,csize);
//			break;
//		case 16:
//			LT268_W25QXX_Read(mat,foffset+FlashAddr,csize);
//			break;
//		case 24:
//			LT268_W25QXX_Read(mat,foffset+FlashAddr,csize);
//			break;
//	}
}

//显示一个指定大小的GB2312编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *font)
{
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	for(t=0;t<csize;t++)
	{
		temp=dzk[t];			//得到点阵数据     
		

		for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
			else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
			temp<<=1;
			x++;
			if((x-x0)==size)
			{
				x=x0;
				y++;
				break;
			}
		}
	}
}

//旋转显示一个指定大小的GB2312编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312_whirl(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *font,UINT8 direction)
{
	UINT16 y0;
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	if(direction==0)
	{
		for(t=0;t<csize;t++)
		{
			temp=dzk[t];			//得到点阵数据     
			

			for(t1=0;t1<8;t1++)
			{
				if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
				else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
				temp<<=1;
				x++;
				if((x-x0)==size)
				{
					x=x0;
					y++;
					break;
				}
			}
		}		
	}
	else if(direction==1)
	{
//		y=y+size;
		y0=y;
		
		for(t=0;t<csize;t++)
		{
			temp=dzk[t];			//得到点阵数据     
			
			for(t1=0;t1<8;t1++)
			{
				if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
				else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
				temp<<=1;
				y--;
				if((y0-y)==size)
				{
					y=y0;
					x++;
					break;
				}
			}
		}		
	}
	else if(direction==2)
	{
//		x=x+size;
		y0=y;
		for(t=0;t<csize;t++)
		{
			temp=dzk[t];			//得到点阵数据     
			
			for(t1=0;t1<8;t1++)
			{
				if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
				else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
				temp<<=1;
				y++;
				if((y-y0)==size)
				{
					y=y0;
					x--;
					break;
				}
			}
		}	
	}
	else if(direction==3)
	{
//		x=x+size;
//		y=y+size;
		x0=x;
		for(t=0;t<csize;t++)
		{
			temp=dzk[t];			//得到点阵数据     
			
			for(t1=0;t1<8;t1++)
			{
				if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
				else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
				temp<<=1;
				x--;
				if((x0-x)==size)
				{
					x=x0;
					y--;
					break;
				}
			}
		}	
	}
}

//旋转90度显示一个指定大小的GB2312编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312_90d(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *font)
{
	UINT16 y0;
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	x=x+size;
	y0=y;
	for(t=0;t<csize;t++)
	{
		temp=dzk[t];			//得到点阵数据     
		
		for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
			else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
			temp<<=1;
			y++;
			if((y-y0)==size)
			{
				y=y0;
				x--;
				break;
			}
		}
	}
}

//旋转180度显示一个指定大小的GB2312编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312_180d(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *font)
{
	UINT16 y0;
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	x=x+size;
	y=y+size;
	x0=x;
	
	for(t=0;t<csize;t++)
	{
		temp=dzk[t];			//得到点阵数据     
		
		for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
			else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
			temp<<=1;
			x--;
			if((x0-x)==size)
			{
				x=x0;
				y--;
				break;
			}
		}
	}
}

//旋转270度显示一个指定大小的GB2312编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312_270d(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT8 *font)
{
	UINT16 y0;
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	y=y+size;
	y0=y;
	
	for(t=0;t<csize;t++)
	{
		temp=dzk[t];			//得到点阵数据     
		
		for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
			else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
			temp<<=1;
			y--;
			if((y0-y)==size)
			{
				y=y0;
				x++;
				break;
			}
		}
	}
}

//显示一个指定大小的GB231编码
//x,y :坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//font:GB231编码
void LT768_TFT_Show_Outside_GB2312_UserDefineFont(UINT16 x,UINT16 y,UINT8 size,UINT8 mode,UINT32 FlashAddr,UINT16 FontColor,UINT16 BackGroundColor,UINT16 font)
{
	UINT8 temp,t1;
	UINT16 x0=x,t;
	UINT8 dzk[1024];
	UINT16 csize=(size/8+((size%8)?1:0))*(size);//得到字体一个字符对应点阵集所占的字节数
//	//if(size!=16&&size!=24&&size!=32)return;	//不支持的size
//	LT768_TFT_Get_HzMat(font,dzk,csize,FlashAddr);	//得到相应大小的点阵数据

	LT_ReadFlash(dzk,FlashAddr+font*csize,csize);
	
	for(t=0;t<csize;t++)
	{
		temp=dzk[t];			//得到点阵数据     
		
		for(t1=0;t1<8;t1++)
		{
			if(temp&0x80)LT768_DrawPoint(x,y,FontColor);
			else if(mode==0)LT768_DrawPoint(x,y,BackGroundColor);
			temp<<=1;
			x++;
			if((x-x0)==size)
			{
				x=x0;
				y++;
				break;
			}
		}
	}
}

//显示一段中英文的字符串
//x,y :汉字的坐标
//size:字体大小
//mode: 0：背景透明  1：透明不背景
//FlashAddr:字库地址
//FontColor:字体颜色
//BackGroundColor:背景颜色
//String_Length:字符串长度
//str:字符串
extern UINT8 C0_gNumRow;

volatile u8 val_blank = 0;
void LT768_TFT_ShowString(unsigned short x,unsigned short y,unsigned short w,unsigned char size,unsigned char mode,unsigned long FlashAddr,unsigned short FontColor,unsigned short BackGroundColor,unsigned short String_Length,unsigned char*str)
{
	UINT16 i=0,temp=0;
	s16 count = String_Length;
	UINT16 x1=x;
	C0_gNumRow=1;

    while(count>0)//数据未结束
    {
        if(str[i]<0xA1)   //---------内部_ASCII编码--------
        {
			if(x+size/2>x1+w)//换行
			{
				y+=size;
				x=x1;
				C0_gNumRow++;
			}
			if(str[i]==13)//换行符号
			{
				y+=size;
				x=x1;
				i++;
				count--;					
				C0_gNumRow++;
			}
			if(y+size>LCD_YSIZE_TFT)
			{
				C0_gNumRow--;
				break;//越界返回
			}
			else
			{
				LT768_TFT_Show_Internal_Char(x,y,size,mode,FontColor,BackGroundColor,str[i]);//有效部分写入
			}
			i++;
			x+=size/2; //字符,为全字的一半
			count--;
        }
        else          	 //-----外部_GB2312编码-------
        {
			if(x+size>x1+w)//换行
			{
				y+=size;
				x=x1;
				C0_gNumRow++;
			}
			if(y+size>LCD_YSIZE_TFT)
			{
				C0_gNumRow--;
				break;//越界返回
			}
			 LT768_TFT_Show_Outside_GB2312(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i]); //有效部分写入	
			
			if(str[i]<0xA4)  		//(当前)字符间距
			{
				temp=str[i+1]-0xA0;
				if(size==16)	    x+=gb2312_char_16[temp]+7;
				else if(size==24)	x+=gb2312_char_24[temp]+6;
				else if(size==32)	x+=gb2312_char_32[temp]+1;
				else if(size==48)	x+=gb2312_char_48[temp];  
				else if(size==72)	x+=gb2312_char_72[temp];
				else  x+=size;

			}				
			else {x+=size+val_blank;}			//(当前)中文间距
			i+=2;
			count-=2;
        }
    }
}


void LT768_TFT_ShowString_font(u16 x,u16 y,u16 w,u8 size,u8 mode,u32 FlashAddr,u16 FontColor,u16 BackGroundColor,u8 alignment,u16 *width_line,u16 String_Length,u8 *str)
{
	u8 num=0;
	u8 y1;
	UINT16 i=0,temp=0;
	s16 count = String_Length;
	UINT16 x1=x;
	C0_gNumRow=1;
	u8 Ascii_temp=0;
	u8 tran_buf[2]={0};

	if(R_angle==0)
	{
		x1=x;
		if(alignment==0)		x=x1;
		else if(alignment==1)	x=x1+(w-width_line[num]);
		
		while(count>0)//数据未结束
		{
			if(str[i]<0xA1)   //---------内部_ASCII编码--------
			{
				if(str[i]==13)//换行符号
				{
					y+=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1+(w-width_line[num]);
					i++;
					count--;					
//					C0_gNumRow++;
					continue;
				}				
				
				Ascii_temp = str[i] - 0x20;
				
				if(x + ASCII_W[Ascii_temp] + 1>x1+w)//换行
				{
					y+=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1+(w-width_line[num]);
					
//					C0_gNumRow++;
				}

				if(y+size>LCD_YSIZE_TFT)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				else
				{
					tran_buf[0] = 0xA3;
					tran_buf[1] = str[i]+0x80;
					if(tran_buf[1]>=0xA1)	LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&tran_buf[0],0); //空格编码不写入				
				}
				
				x = x + (ASCII_W[Ascii_temp] + 1); //字符宽度为自定义
				i++;
				count--;
			}
			else          	 //-----外部_GB2312编码-------
			{
				if(x+size>x1+w)//换行
				{
					y+=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1+(w-width_line[num]);
//					C0_gNumRow++;
				}
				if(y+size>LCD_YSIZE_TFT)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				 LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i],0); //有效部分写入	
				
				if(str[i]<0xA4)  		//(当前)字符间距
				{
					temp=str[i+1]-0xA0;
					if(size==16)	    x+=gb2312_char_16[temp]+7;
					else if(size==24)	x+=gb2312_char_24[temp]+6;
					else if(size==32)	x+=gb2312_char_32[temp]+1;
					else if(size==48)	x+=gb2312_char_48[temp];  
					else if(size==72)	x+=gb2312_char_72[temp];
					else  x = x+size;

				}				
				else {x=x+size+val_blank;}			//(当前)中文间距
				i+=2;
				count-=2;
			}
		}
	}
	else if(R_angle==1)
	{
		y1=y;
		if(alignment==0)		y=y1;
		else if(alignment==1)	y=y1-(w-width_line[num]);
		
		while(count>0)//数据未结束
		{
			if(str[i]<0xA1)   //---------内部_ASCII编码--------
			{
				if(str[i]==13)//换行符号
				{
					x+=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1-(w-width_line[num]);
					i++;
					count--;					
//					C0_gNumRow++;
					continue;
				}				
				
				Ascii_temp = str[i] - 0x20;
				
				if(y - ASCII_W[Ascii_temp] - 1<y1-w)//换行
				{
					x+=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1-(w-width_line[num]);
//					C0_gNumRow++;
				}

				if(x+size>LCD_XSIZE_TFT)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				else
				{
					tran_buf[0] = 0xA3;
					tran_buf[1] = str[i]+0x80;
					if(tran_buf[1]>=0xA1)	LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&tran_buf[0],1); //空格编码不写入				
				}
				
				y = y - (ASCII_W[Ascii_temp]+1); //字符宽度为自定义
				i++;
				count--;
			}
			else          	 //-----外部_GB2312编码-------
			{
				if(y-size<y1-w)//换行
				{
					x+=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1-(w-width_line[num]);
//					C0_gNumRow++;
				}
				if(x+size>LCD_XSIZE_TFT)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				 LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i],1); //有效部分写入	
				
				if(str[i]<0xA4)  		//(当前)字符间距
				{
					temp=str[i+1]-0xA0;
					if(size==16)	    y-=gb2312_char_16[temp]+7;
					else if(size==24)	y-=gb2312_char_24[temp]+6;
					else if(size==32)	y-=gb2312_char_32[temp]+1;
					else if(size==48)	y-=gb2312_char_48[temp];  
					else if(size==72)	y-=gb2312_char_72[temp];
					else  y-=size;

				}				
				else {y=y-size-val_blank;}			//(当前)中文间距
				i+=2;
				count-=2;
			}
		}
	}	
	else if(R_angle==2)
	{
		y1=y;
		if(alignment==0)		y=y1;
		else if(alignment==1)	y=y1+(w-width_line[num]);		
		while(count>0)//数据未结束
		{
			if(str[i]<0xA1)   //---------内部_ASCII编码--------
			{
				if(str[i]==13)//换行符号
				{
					x-=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1+(w-width_line[num]);
					i++;
					count--;					
//					C0_gNumRow++;
					continue;
				}				
				Ascii_temp = str[i] - 0x20;
				if(y + ASCII_W[Ascii_temp] + 1>y1+w)//换行
				{
					x-=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1+(w-width_line[num]);
//					C0_gNumRow++;
				}
				if(x-size<0)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				else
				{
					tran_buf[0] = 0xA3;
					tran_buf[1] = str[i]+0x80;
					if(tran_buf[1]>=0xA1)	LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&tran_buf[0],2); //空格编码不写入				
				}
				
				y = y + ASCII_W[Ascii_temp] + 1; //字符宽度为自定义
				i++;
				count--;
			}
			else          	 //-----外部_GB2312编码-------
			{
				if(y+size>y1+w)//换行
				{
					x-=size;
					num++;
					if(alignment==0)		y=y1;
					else if(alignment==1)	y=y1+(w-width_line[num]);
//					C0_gNumRow++;
				}
				if(x-size<0)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				 LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i],2); //有效部分写入	
				
				if(str[i]<0xA4)  		//(当前)字符间距
				{
					temp=str[i+1]-0xA0;
					if(size==16)	    y+=gb2312_char_16[temp]+7;
					else if(size==24)	y+=gb2312_char_24[temp]+6;
					else if(size==32)	y+=gb2312_char_32[temp]+1;
					else if(size==48)	y+=gb2312_char_48[temp];  
					else if(size==72)	y+=gb2312_char_72[temp];
					else  y+=size;

				}				
				else {y=y+size+val_blank;}			//(当前)中文间距
				i+=2;
				count-=2;
			}
		}
	}
	else if(R_angle==3)
	{
		x1=x;
		if(alignment==0)		x=x1;
		else if(alignment==1)	x=x1-(w-width_line[num]);
		while(count>0)//数据未结束
		{
			if(str[i]<0xA1)   //---------内部_ASCII编码--------
			{
				if(str[i]==13)//换行符号
				{
					y-=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1-(w-width_line[num]);
					i++;
					count--;					
//					C0_gNumRow++;
					continue;
				}				
				Ascii_temp = str[i] - 0x20;				
				if(x - ASCII_W[Ascii_temp] - 1<x1-w)//换行
				{
					y-=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1-(w-width_line[num]);
//					C0_gNumRow++;
				}

				if(y-size<0)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				else
				{
	//				LT768_TFT_Show_Internal_Char(x,y,size,mode,FontColor,BackGroundColor,str[i]);//有效部分写入
					tran_buf[0] = 0xA3;
					tran_buf[1] = str[i]+0x80;
					if(tran_buf[1]>=0xA1)	LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&tran_buf[0],3); //空格编码不写入				
				}
				
				x = x - (ASCII_W[Ascii_temp]+1); //字符宽度为自定义
				i++;
				count--;
			}
			else          	 //-----外部_GB2312编码-------
			{
				if(x-size<x1-w)//换行
				{
					y-=size;
					num++;
					if(alignment==0)		x=x1;
					else if(alignment==1)	x=x1-(w-width_line[num]);
//					C0_gNumRow++;
				}
				if(y-size<0)
				{
//					C0_gNumRow--;
					break;//越界返回
				}
				 LT768_TFT_Show_Outside_GB2312_whirl(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i],3); //有效部分写入	
				
				if(str[i]<0xA4)  		//(当前)字符间距
				{
					temp=str[i+1]-0xA0;
					if(size==16)	    x-=gb2312_char_16[temp]+7;
					else if(size==24)	x-=gb2312_char_24[temp]+6;
					else if(size==32)	x-=gb2312_char_32[temp]+1;
					else if(size==48)	x-=gb2312_char_48[temp];  
					else if(size==72)	x-=gb2312_char_72[temp];
					else  x-=size;

				}				
				else {x=x-size-val_blank;}			//(当前)中文间距
				i+=2;
				count-=2;
			}
		}
	}
}

/***************将8位色深转为16位*********************/
UINT16 LT_Color8_To_16(UINT8 color)
{
/*	UINT16 r,g,b;
	r = ((color>>5)&0x07)*4;
	g = ((color>>2)&0x07)*8;
	b = ((color>>0)&0x03)*8;
//	r = ((color>>16)&0xff)/8;
//	g = ((color>>8)&0xff)/4;
//	b = ((color>>0)&0xff)/8;
	return ((r<<11)+(g<<5)+b);
	*/
	
	UINT16 r,g,b;
	r = (color>>5)&0x07;
	g = (color>>2)&0x07;
	b = (color>>0)&0x03;
	
	if(r==0)  r=0;
	else if (r==7)  r=31;
		else r=5*r;
		
	if(g==0)  g=0;
	else if (g==7)  g=63;
		else g=10*g+1;
		
	if(b==0)  b=0;
	else if (b==3)  b=31;
		else b=15*b;

	return ((r<<11)+(g<<5)+b);
}

void LT768_TFT_ShowString_48_72(unsigned short x,unsigned short y,unsigned short w,unsigned char size,unsigned char mode,unsigned long FlashAddr,unsigned short FontColor,unsigned short BackGroundColor,unsigned short String_Length,unsigned char*str)
{
	UINT16 i=0,temp=0;
	s16 count = String_Length;
	UINT16 x1=x;
	C0_gNumRow=1;

    while(count>0)//数据未结束
    {
//        if(str[i]<0xA1)   //---------内部_ASCII编码--------
//        {
//			if(x+size/2>x1+w)//换行
//			{
//				y+=size;
//				x=x1;
//				C0_gNumRow++;
//			}
//			if(str[i]==13)//换行符号
//			{
//				y+=size;
//				x=x1;
//				i++;
//				count--;					
//				C0_gNumRow++;
//			}
//			if(y+size>LCD_YSIZE_TFT)
//			{
//				C0_gNumRow--;
//				break;//越界返回
//			}
//			else
//			{
//				LT768_TFT_Show_Internal_Char(x,y,size,mode,FontColor,BackGroundColor,str[i]);//有效部分写入
//			}
//			i++;
//			x+=size/2; //字符,为全字的一半
//			count--;
//        }
//        else          	 //-----外部_GB2312编码-------
//        {
			if(x+size>x1+w)//换行
			{
				y+=size;
				x=x1;
				C0_gNumRow++;
			}
			if(y+size>LCD_YSIZE_TFT)
			{
				C0_gNumRow--;
				break;//越界返回
			}
			 LT768_TFT_Show_Outside_GB2312(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,&str[i]); //有效部分写入	
			
//			if(str[i]<0xA4)  		//(当前)字符间距
//			{
//				temp=str[i+1]-0xA0;
//				if(size==16)	    x+=gb2312_char_16[temp]+7;
//				else if(size==24)	x+=gb2312_char_24[temp]+6;
//				else if(size==32)	x+=gb2312_char_32[temp]+1;
//				else if(size==48)	x+=gb2312_char_48[temp];  
//				else if(size==72)	x+=gb2312_char_72[temp];
//				else  x+=size;

//			}				
//			else {x+=size+val_blank;}			//(当前)中文间距
			x+=size;
			i+=2;
			count-=2;
//        }
    }
}

int Get_User_Font_P(char chH,char chL)
{
	int i;
	
	for(i=0;i<(sizeof(Font_1)/2);i++)
	{
		if((chH == Font_1[i*2])&&(chL == Font_1[i*2+1]))
		{
			return i;
		}
	}
	
	return -1;
}

void LT768_TFT_ShowString_48_72_UserDefineFont(unsigned short x,unsigned short y,unsigned short w,unsigned char size,unsigned char mode,unsigned long FlashAddr,unsigned short FontColor,unsigned short BackGroundColor,unsigned short String_Length,unsigned char*str)
{
	UINT16 i=0;
	s16 count = String_Length;
	UINT16 x1=x;
	C0_gNumRow=1;
	s16 temp=0;
	
    while(count>0)//数据未结束
    {
//        if(str[i]<0xA1)   //---------内部_ASCII编码--------
//        {
//			if(x+size/2>x1+w)//换行
//			{
//				y+=size;
//				x=x1;
//				C0_gNumRow++;
//			}
//			if(str[i]==13)//换行符号
//			{
//				y+=size;
//				x=x1;
//				i++;
//				count--;					
//				C0_gNumRow++;
//			}
//			if(y+size>LCD_YSIZE_TFT)
//			{
//				C0_gNumRow--;
//				break;//越界返回
//			}
//			else
//			{
//				LT768_TFT_Show_Internal_Char(x,y,size,mode,FontColor,BackGroundColor,str[i]);//有效部分写入
//			}
//			i++;
//			x+=size/2; //字符,为全字的一半
//			count--;
//        }
//        else          	 //-----外部_GB2312编码-------
//        {

			temp = Get_User_Font_P(str[i],str[i+1]);
			if(temp == -1)	break;

			if(x+size>x1+w)//换行
			{
				y+=size;
				x=x1;
				C0_gNumRow++;
			}
			if(y+size>LCD_YSIZE_TFT)
			{
				C0_gNumRow--;
				break;//越界返回
			}
			 LT768_TFT_Show_Outside_GB2312_UserDefineFont(x,y,size,mode,FlashAddr,FontColor,BackGroundColor,(u16)temp); //有效部分写入	
			
//			if(str[i]<0xA4)  		//(当前)字符间距
//			{
//				temp=str[i+1]-0xA0;
//				if(size==16)	    x+=gb2312_char_16[temp]+7;
//				else if(size==24)	x+=gb2312_char_24[temp]+6;
//				else if(size==32)	x+=gb2312_char_32[temp]+1;
//				else if(size==48)	x+=gb2312_char_48[temp];  
//				else if(size==72)	x+=gb2312_char_72[temp];
//				else  x+=size;

//			}				
//			else {x+=size+val_blank;}			//(当前)中文间距
			x+=size;
			i+=2;
			count-=2;
//        }
    }
}

#include "pwm.h"
extern PWM_HandleTypeDef hBlPwm;
void LT_BacklightSet(UINT16 duty)
{
//	PWM->PWM_CMR3 = duty;
//	LT768_PWM1_Duty(duty);
	
	DRV_PWM_ConfigCHxWidth(PWM,0,duty);
}



void TriangleFill_Top_to_Bottom(unsigned short x1,unsigned short y1,
							    unsigned short x2,unsigned short y2,
				                unsigned short x3,unsigned short y3,
			                    unsigned long color)      //point2和point3 同一Y轴位置，point1 Y轴小于point2Y轴、X轴任意
{
	//A点(x1,y1);	B点(x2,y2);		C点(x3,y3)
	float curx1 = x1;
	float curx2 = x1;

	for (int scanlineY = y1; scanlineY <= y2; scanlineY++)
	{	
		//先下扫
		LT768_DrawLine((int)curx1,scanlineY,(int)curx2,scanlineY,color);
		curx1  = x1+(scanlineY-y1+1)*(x2 - x1) / (y2 - y1);
		curx2  = x1+(scanlineY-y1+1)*(x3 - x1) / (y3 - y1);

	}
}

void TriangleFill_Bottom_to_Top(unsigned short x1,unsigned short y1,
							    unsigned short x2,unsigned short y2,
				                unsigned short x3,unsigned short y3,
			                    unsigned long color)      //point2和point3 同一Y轴位置，point1 Y轴大于point2Y轴、X轴任意
{
	//A点(x1,y1);	B点(x2,y2);		C点(x3,y3)
	float curx1 = x1;
	float curx2 = x1;

	for (int scanlineY = y1; scanlineY >= y2; scanlineY--)
	{
				
		//先上扫
		LT768_DrawLine((int)curx1,scanlineY,(int)curx2,scanlineY,color);
		curx1  = x1-(y1-scanlineY+1)*(x2 - x1) / (y2 - y1);
		curx2  = x1-(y1-scanlineY+1)*(x3 - x1) / (y3 - y1);
	}
}

typedef struct
{
    unsigned short x;
    unsigned short y;
}Point;
Point NewPoint(Point p1, Point p2, unsigned short y)  //两点确定一条直线，输入Y轴得到X轴
{
    Point p;
    p.x = 0;
    p.y = y;
    float temp = 0;
    temp = (float)p2.x - (((float)p2.y - (float)y) * ((float)p2.x - (float)p1.x) / ((float)p2.y - (float)p1.y));
    
    p.x = (unsigned short)temp;
    return p;
}
void Find_Point_Draw(Point p1, Point p2, Point p3,unsigned short color)
{
    Point a; //最终调用扫描函数的上顶点
    Point b; //最终调用扫描函数的平底线左端点
    Point c; //最终调用扫描函数的平底线右端点
    Point d; //最终调用扫描函数的下顶点

    a.x = a.y = b.x = b.y = c.x = c.y = d.x = d.y = 0;
    //两点平行的情况
    if (p1.y == p2.y)
    {
        if (p1.x < p2.x) //p1 为左端点
        {
            b = p1; c = p2;
            if (p3.y < p1.y)
            {
                a = p3;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p3.y > p1.y)
            {
                d = p3;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
        else //p2作为左端点
        {
            b = p2; c = p1;
            if (p3.y < p1.y)
            {
                a = p3;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p3.y > p1.y)
            {
                d = p3;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
    }
    else if (p1.y == p3.y)
    {
        if (p1.x < p3.x) //p1 为左端点
        {
            b = p1; c = p3;
            if (p2.y < p1.y)
            {
                a = p2;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p2.y > p1.y)
            {
                d = p2;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
        else //p3作为左端点
        {
            b = p3; c = p1;
            if (p2.y < p1.y)
            {
                a = p2;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p2.y > p1.y)
            {
                d = p2;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
    }
    else if (p2.y == p3.y)
    {
        if (p2.x < p3.x) //p2 为左端点
        {
            b = p2; c = p3;
            if (p1.y < p2.y)
            {
                a = p1;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p1.y > p2.y)
            {
                d = p1;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
        else //p3作为左端点
        {
            b = p3; c = p2;
            if (p1.y < p2.y)
            {
                a = p1;
                /*
                  TriangleFill_Top_to_Bottom
                  only a b c

                */
				TriangleFill_Top_to_Bottom(a.x, a.y, b.x, b.y, c.x, c.y,color);
//                printf("a:(%d,%d) \r\nb:(%d,%d) \r\nc:(%d,%d) \r\n", a.x, a.y, b.x, b.y, c.x, c.y);
                return;
            }
            else if (p1.y > p2.y)
            {
                d = p1;
                /*
                  TriangleFill_Bottom_to_Top
                  only b c d
                */
				TriangleFill_Bottom_to_Top(d.x,d.y,b.x,b.y,c.x,c.y,color);
//                printf("b:(%d,%d) \r\nc:(%d,%d) \r\nd:(%d,%d) \r\n", b.x, b.y, c.x, c.y, d.x, d.y);
                return;
            }
        }
    }

}

void Find_Point(Point p1,Point p2,Point p3,unsigned short color)
{
    Point a; //最终调用扫描函数的上顶点
    Point b; //最终调用扫描函数的平底线左端点
    Point c; //最终调用扫描函数的平底线右端点
    Point d; //最终调用扫描函数的下顶点
    Point temp,temp1, temp2, temp3,New;
    unsigned char Flag = 0;

    a.x = a.y = b.x = b.y = c.x = c.y = d.x = d.y = 0;
    temp.x = temp.y = temp1.x = temp1.y = 0;
    temp2.x = temp2.y = temp3.x = temp3.y = 0;
     
    //两点平行的情况
    if (p1.y == p2.y || p1.y == p3.y || p2.y == p3.y)
        Find_Point_Draw(p1, p2, p3,color);
  

    //两点垂直的情况
    if (p1.x == p2.x)
    {
        temp3 = p3;
        if (p1.y < p2.y)
        {
            temp1 = p1;
            temp2 = p2;
        }
        else
        {
            temp1 = p2;
            temp2 = p1;
        }
        Flag = 1;
    }
    else if (p1.x == p3.x)
    {
        temp3 = p2;
        if (p1.y < p3.y)
        {
            temp1 = p1;
            temp2 = p3;
        }
        else
        {
            temp1 = p3;
            temp2 = p1;
        }
        Flag = 1;
    }
    else if (p2.x == p3.x)
    {
        temp3 = p1;
        if (p2.y < p3.y)
        {
            temp1 = p2;
            temp2 = p3;
        }
        else
        {
            temp1 = p3;
            temp2 = p2;
        }
        Flag = 1;
    }
    if (Flag)
    {
        if (temp3.y < temp1.y)
        {
            New = NewPoint(temp3, temp2, temp1.y);
            Find_Point_Draw(New, temp3, temp1,color);
            Find_Point_Draw(New, temp1, temp2,color);
        }
        else if (temp3.y > temp1.y && temp3.y < temp2.y)
        {
            New = NewPoint(temp1, temp2, temp3.y);
            Find_Point_Draw(New, temp1, temp3,color);
            Find_Point_Draw(New, temp2, temp3,color);
        }
        else if (temp3.y > temp2.y)
        {
            New = NewPoint(temp1, temp3, temp2.y);
            Find_Point_Draw(New, temp1, temp2,color);
            Find_Point_Draw(New, temp2, temp3,color);
        }
        Flag = 0;
    }

    //其他

    //三点按X轴大小排列
    if (p1.x < p2.x)
    {
        temp1 = p1;
        if (p3.x < p1.x)
        {
            temp1 = p3;
            temp2 = p1;
            temp3 = p2;
        }
        else
        {
            if (p3.x < p2.x)
            {
                temp1 = p1;
                temp2 = p3;
                temp3 = p2;
            }
            else
            {
                temp1 = p1;
                temp2 = p2;
                temp3 = p3;
            }
        }
    }
    else
    {
        if (p2.x < p3.x)
        {
            if (p3.x < p1.x)
            {
                temp1 = p2;
                temp2 = p3;
                temp3 = p1;
            }
            else
            {
                temp1 = p2;
                temp2 = p1;
                temp3 = p3;
            }
        }
        else
        {
            temp1 = p3;
            temp2 = p2;
            temp3 = p1;
        }
    }

    if ((temp1.y > temp2.y && temp1.y < temp3.y) || (temp1.y > temp3.y && temp1.y < temp2.y))
    {
        New = NewPoint(temp2, temp3, temp1.y);
        Find_Point_Draw(New, temp1, temp2,color);
        Find_Point_Draw(New, temp1, temp3,color);
    }
    else if ((temp1.y > temp2.y && temp1.y > temp3.y)  && (temp2.y>temp3.y))   
    {
        New = NewPoint(temp1, temp3, temp2.y);
        Find_Point_Draw(New, temp2, temp1,color);
        Find_Point_Draw(New, temp2, temp3,color);
    }
    else if ((temp1.y > temp2.y && temp1.y > temp3.y) && (temp2.y < temp3.y))   
    {
        New = NewPoint(temp1, temp2, temp3.y);
        Find_Point_Draw(New, temp3, temp1,color);
        Find_Point_Draw(New, temp3, temp2,color);
    }
    else if ((temp1.y < temp2.y && temp1.y < temp3.y) && (temp2.y > temp3.y))
    {
        New = NewPoint(temp1, temp2, temp3.y);
        Find_Point_Draw(New, temp3, temp1,color);
        Find_Point_Draw(New, temp3, temp2,color);
    }
    else if ((temp1.y < temp2.y && temp1.y < temp3.y) && (temp2.y < temp3.y))
    {
        New = NewPoint(temp1, temp3, temp2.y);
        Find_Point_Draw(New, temp2, temp1,color);
        Find_Point_Draw(New, temp2, temp3,color);
    }

}

void LT768_DrawTriangle_Fill(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2,unsigned short x3,unsigned short y3,unsigned long color)
{
	Point p1,p2,p3;
	p1.x=x1;
	p1.y=y1;
	p2.x=x2;
	p2.y=y2;
	p3.x=x3;
	p3.y=y3;
	
	Find_Point(p1,p2,p3,color);	
}

//解压图片所用的变量
ctb_data CTB;
unsigned char  RTBuff[2048];
__align(4) unsigned short*RowBuff;
__align(4) unsigned short RowBuff_1[1024+1];
__align(4) unsigned short RowBuff_2[1024+1];
u8 Table_color[512];
__align(4) unsigned short RowBuff_OLD;



