/******************************************************************************
�� �� ����TFT_LCD.c
����������TFT��ɫҺ����ʾ�����ƺ������ļ�
��    �ߣ�����
��    ����V1.0
��    �ڣ�2017.4.8
******************************************************************************/
#include "Include.h"
//#include "TFT_LCD.h"
#define sizeofLCD 50

TFTLCDDrawingFIFOStruct     TFTLCDDrawingFIFO;
TFTLCDUpdateCtrlStruct    TFTLCDUpdateCtrl;

static ArrayBuffStruct buff_array;
static PixelPointList pixelPointList;
static void Uncompress_Clean();

extern TFTLCDUpdateCtrlStruct    TFTLCDUpdateCtrl;

/**************************************************************************/

void TFT_LCD_Draw_Vertical_Line(uint16_t PosX, uint16_t StartY, uint16_t EndY, uint8_t Type)
{
  Original_TFT_LCD_Draw_Vertical_Line(PosX, StartY, EndY, Type); 
}

void TFT_LCD_Draw_Horizontal_Line(uint16_t StartX, uint16_t EndX, uint16_t PosY, uint8_t Type)
{
  Original_TFT_LCD_Draw_Horizontal_Line( StartX, EndX, PosY, Type);
}

void TFT_LCD_Draw_Bmp(uint8_t Comp, uint8_t Inv, uint16_t StartX, uint16_t StartY, uint8_t * __far pBmp)
{
  Original_TFT_LCD_Draw_Bmp(Comp, Inv, StartX, StartY, pBmp);
}

void TFT_LCD_Draw_Box(uint16_t StartX, uint16_t StartY, uint16_t EndX, uint16_t EndY, uint8_t Fill, uint8_t Type)
{
  Original_TFT_LCD_Draw_Box( StartX, StartY, EndX, EndY, Fill, Type);
}
//���ܣ�ÿ�λ����µ�ͼƬ��Ӧ��buff��־λ��λ
/****************************************************************************/
static void Uncompress_Clean()
{
    buff_array.arrayInPosCur = 0;
    buff_array.arrayPosCur = 0;
    buff_array.arrayTotolPosCur = 0;    
    pixelPointList.Top_Pos = 0; 
}
//////////////////////////////////////////////////////////////////////////////
void lcd_init_test(void);
void lcd_init_test(void)
{
  INT8U i=0;
      for (i = 0; i < TFT_LCD_REQ_FIFO_MAX_DEPTH; i++)
        TFTLCDDrawingFIFO.Req[i].Mode = TFT_LCD_MODE_IDLE;
      
      TFTLCDDrawingFIFO.Iptr          = 0;
      TFTLCDDrawingFIFO.Optr          = 0;  
      TFTLCDDrawingFIFO.Depth         = 0; 
}
//////////////////////////////////////////////////////////////////////////////
/******************************************************************************
��������TFT_LCD_Startup
��  �ܣ�����TFTҺ����ʾ��
��  ������
����ֵ����
******************************************************************************/
void TFT_LCD_BUF_Clean(void)
{
INT8U i=0;
      Uncompress_Clean();
      for (i = 0; i < TFT_LCD_REQ_FIFO_MAX_DEPTH; i++)
        TFTLCDDrawingFIFO.Req[i].Mode = TFT_LCD_MODE_IDLE;
      
      TFTLCDDrawingFIFO.Iptr          = 0;
      TFTLCDDrawingFIFO.Optr          = 0;  
      TFTLCDDrawingFIFO.Depth         = 0; 

      TFTLCDUpdateCtrl.Brightness  = 0;   
}
void TFT_LCD_Startup(void)
{

   if(TFT_INIT==0)
   {
       
      LCD_Init();

      TFT_LCD_BUF_Clean(); 
       TFT_INIT =1;
   }
}

/******************************************************************************
��������TFT_LCD_Shutdown
��  �ܣ��ر�TFTҺ����ʾ��
��  ������
����ֵ����
******************************************************************************/
void TFT_LCD_Shutdown(void)
{

if(1==TFT_INIT)
{
  LCD_Shutdown();
  TFT_INIT = 0;
}  
}

/******************************************************************************
��������TFT_LCD_Busy_Check
��  �ܣ����TFTҺ����ʾ������״̬
��  ������
����ֵ��0 - TFTҺ����ʾ�����ڿ���״̬
        1 - TFTҺ����ʾ��������
        2 - TFTҺ����ʾ����ʾ����FIFO����,�����ٽ����»�ͼ����
******************************************************************************/
uint8_t TFT_LCD_Busy_Check(void)
{
  /*if (TFTLCDDrawingFIFO.Depth == 0)
    return 0;
  else if (TFTLCDDrawingFIFO.Depth < TFT_LCD_REQ_FIFO_MAX_DEPTH)
    return 1;*/
  
  return 2;
}

/******************************************************************************
��������TFT_LCD_Set_Brightness
��  �ܣ�TFTҺ����ʾ���������ȿ���
��  ����Br�����ȵȼ� 0(�) - 100(����)
����ֵ����
******************************************************************************/
void TFT_LCD_Set_Brightness(uint8_t Br)
{
	/*if (Br > 100)
	  Br = 100;
	
	if (Br != TFTLCDUpdateCtrl.Brightness)
	{
	  TFTLCDUpdateCtrl.Brightness = Br;
	  PWM_Channel_Set_Duty_Cycle(1, Br);
	}*/
}

/******************************************************************************
��������TFT_LCD_Display_Update_Service
��  �ܣ�TFT��ɫҺ����ʾ����ʾ���·���
��  ������
����ֵ����
*******************************************************************************
ע  �⣺�÷���������ÿ��ϵͳ����ʱʵʱ����
******************************************************************************/

void TFT_LCD_Display_Update_Service(void)
{
  uint8_t Done;
  
  if (TFTLCDDrawingFIFO.Depth)
  {
    switch (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr].Mode)
    {
      case TFT_LCD_MODE_CLEAR : Done = TFT_LCD_Cls_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      case TFT_LCD_MODE_DBMP  : Done = TFT_LCD_Direct_Draw_Bmp_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      case TFT_LCD_MODE_IBMP  : Done = TFT_LCD_Insert_Draw_Bmp_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      case TFT_LCD_MODE_DTBMP : Done = TFT_LCD_Direct_Draw_Transparent_Bmp_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      case TFT_LCD_MODE_ITBMP : Done = TFT_LCD_Insert_Draw_Transparent_Bmp_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;

      case TFT_LCD_MODE_PIXEL : Done = TFT_LCD_Draw_Pixel_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;

      case TFT_LCD_MODE_HLINE : Done = TFT_LCD_Draw_Horizontal_Line_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;

      case TFT_LCD_MODE_VLINE : Done = TFT_LCD_Draw_Vertical_Line_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;                                

      case TFT_LCD_MODE_BBOX  : Done = TFT_LCD_Draw_Box_Border_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;

      case TFT_LCD_MODE_DFBOX : Done = TFT_LCD_Direct_Draw_Full_Box_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      case TFT_LCD_MODE_IFBOX : Done = TFT_LCD_Insert_Draw_Full_Box_Handler(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break; 
                                
      case TFT_LCD_MODE_TEST  : Done = TFT_LCD_Direct_Draw_Bmp_TEST(&TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr]);
                                break;
                                
      default                 : Done = 1;
                                break;
    }
    
    if (Done)
    {
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Optr].Mode = TFT_LCD_MODE_IDLE;
      
      Uncompress_Clean();
            
      //FIFO����
      TFTLCDDrawingFIFO.Depth--;
      TFTLCDDrawingFIFO.Optr++;
      if(TFTLCDDrawingFIFO.Optr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
        TFTLCDDrawingFIFO.Optr = 0;       
    }
  }
}

/******************************************************************************
��������TFT_LCD_Cls
��  �ܣ����TFTҺ����ʾ��ȫ����ʾ
��  ������
����ֵ����
******************************************************************************/
void TFT_LCD_Cls(void)
{
  /*if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    return;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode            = TFT_LCD_MODE_CLEAR;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State           = TFT_LCD_STATE_INIT;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = 0;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        = 0;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = 79;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          = 239;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = 0;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = 0;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Width           = 240;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Length          = 19200;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Offset          = 0;
  
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0;*/
}

/******************************************************************************
��������TFT_LCD_Draw_Bmp
��  �ܣ���TFTҺ����ʾ��ָ��λ���ϻ��Ʋ�͸��λͼ
        ����ʹStartY����Ϊ8��������,����߻�ͼ�ٶ�
��  ����StartX - ��ͼ��ʼx����
        StartY - ��ͼ��ʼy����
        pBmp   - ͼƬ����
����ֵ����
******************************************************************************/
void Original_TFT_LCD_Draw_Bmp( uint8_t Comp, uint8_t Inv, uint16_t StartX, uint16_t StartY, uint8_t * __far pBmp)
{
  if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
  {
     //TFTLCDDrawingFIFO.Depth = 0;
     return;
  }

 
  if (pBmp == NULL)
    return;
  
//  if ((StartX >= TFT_LCD_X_SIZE) || (StartY >= TFT_LCD_Y_SIZE))
//    return;
  
  if ((StartX + pBmp[0] > TFT_LCD_X_SIZE) || (StartY + pBmp[1] > TFT_LCD_Y_SIZE))
    return;
 
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ((uint8_t)(StartY >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        =  (uint8_t)StartX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = ((uint8_t)((StartY + pBmp[1] - 1) >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          =  (uint8_t)(StartX + pBmp[0] - 1);
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Width           = pBmp[0];
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Length          = (pBmp[1] >> 2) * pBmp[0];
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Offset          = 0;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ((uint8_t)(StartY & 0x0003));  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].pBmp            = pBmp + 2;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].IsCompress      = Comp;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].IsInverse        = Inv;
  
  if (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT == 0)
  {
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode          = TFT_LCD_MODE_DBMP;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_INIT;
  }
  else
  {
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode          = TFT_LCD_MODE_IBMP;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_TOP;
  }
   
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0;
}

/******************************************************************************
��������TFT_LCD_Draw_Transparent_Bmp
��  �ܣ���TFTҺ����ʾ��ָ��λ���ϻ���͸��λͼ
        ����ͨ��TFT_LCD_Draw_Bmp���Ƶ�λͼ,��Ҫʹ�ñ���������
        ����ʹStartY����Ϊ8��������,����߻�ͼ�ٶ�
��  ����StartX - ��ͼ��ʼx����
        StartY - ��ͼ��ʼy����
        pBmp   - ͼƬ����
        Type   - ��ͼ����,������:
                 TFT_LCD_TYPE_SET - ����λͼ,�հ�������͸����ʾ
                 TFT_LCD_TYPE_CLR - ���λͼ�зǿհ�����ͼ��,�հ�������͸����ʾ
                 TFT_LCD_TYPE_INV - ����λͼ�зǿհ�����ͼ��,�հ�������͸����ʾ
����ֵ����
******************************************************************************/
void TFT_LCD_Draw_Transparent_Bmp ( uint16_t StartX, uint16_t StartY, uint8_t *__far pBmp, uint8_t Type )
{
    if ( TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        return;

    if ( pBmp == NULL )
        return;

    if ( ( StartX >= TFT_LCD_X_SIZE ) || ( StartY >= TFT_LCD_Y_SIZE ) )
        return;

    if ( ( StartX + pBmp[0] >= TFT_LCD_X_SIZE ) || ( StartY + pBmp[1] >= TFT_LCD_Y_SIZE ) )
        return;

    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ( ( uint8_t ) ( StartY >> 2 ) );
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        = ( uint8_t ) StartX;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = ( ( uint8_t ) ( ( StartY + pBmp[1] - 1 ) >> 2 ) );
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          = ( uint8_t ) ( StartX + pBmp[0] - 1 );
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Width           = pBmp[0];
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Length          = ( pBmp[1] >> 2 ) * pBmp[0];
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Offset          = 0;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Type            = Type;
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ( ( uint8_t ) ( StartY & 0x0003 ) );
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].pBmp            = pBmp + 2;

    if ( TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT == 0 )
    {
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode          = TFT_LCD_MODE_DTBMP;
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_DRAW;
    }
    else
    {
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode          = TFT_LCD_MODE_ITBMP;
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_TOP;
    }

    //FIFO����
    TFTLCDDrawingFIFO.Depth++;
    TFTLCDDrawingFIFO.Iptr++;

    if ( TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH )
        TFTLCDDrawingFIFO.Iptr = 0;
}

/******************************************************************************
��������TFT_LCD_Draw_Pixel
��  �ܣ���TFTҺ����ʾ��ָ��λ�û���һ�����ص�
��  ����StartX - ���ص�x����
        StartY - ���ص�y����
        Type   - ��ͼ����,������:
                 TFT_LCD_TYPE_SET - �������ص�
                 TFT_LCD_TYPE_CLR - ������ص�
                 TFT_LCD_TYPE_INV - �������ص�
����ֵ����
******************************************************************************/
void TFT_LCD_Draw_Pixel( uint16_t PosX, uint16_t PosY, uint8_t Type)
{
  /*if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    return;
  
  if ((PosX >= TFT_LCD_X_SIZE) || (PosY >= TFT_LCD_Y_SIZE))
    return;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode            = TFT_LCD_MODE_PIXEL;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State           = TFT_LCD_STATE_DRAW;
    
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ((uint8_t)(PosY >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        =  (uint8_t)PosX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;

  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Type            = Type;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ((uint8_t)(PosY & 0x0003));
  
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0;*/
}

/******************************************************************************
��������TFT_LCD_Draw_Horizontal_Line
��  �ܣ���TFTҺ����ʾ��ָ��λ���ϻ���һ��ˮƽ��
��  ����StartX - ��ͼ��ʼx����
        EndX   - ��ͼ����x����
        PosY   - ��ͼy����
        Type   - ��ͼ����,������:
                 TFT_LCD_TYPE_SET - ����ˮƽ��
                 TFT_LCD_TYPE_CLR - ���ˮƽ��
                 TFT_LCD_TYPE_INV - ����ˮƽ��
����ֵ����
******************************************************************************/
void Original_TFT_LCD_Draw_Horizontal_Line(uint16_t StartX, uint16_t EndX, uint16_t PosY, uint8_t Type)
{
  if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    return;
  
  if ((StartX >= TFT_LCD_X_SIZE) || (EndX >= TFT_LCD_X_SIZE) || \
      (PosY   >= TFT_LCD_Y_SIZE))
    return;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode            = TFT_LCD_MODE_HLINE;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State           = TFT_LCD_STATE_DRAW;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ((uint8_t)(PosY >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        =  (uint8_t)StartX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          =  (uint8_t)EndX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;

  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Type            = Type;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ((uint8_t)(PosY & 0x0003));
    
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0;
}

/******************************************************************************
��������TFT_LCD_Draw_Vertical_Line
��  �ܣ���TFTҺ����ʾ��ָ��λ���ϻ���һ����ֱ��
��  ����PosX   - ��ͼx����
        StartY - ��ͼ��ʼy����
        EndY   - ��ͼ����y����
        Type   - ��ͼ����,������:
                 TFT_LCD_TYPE_SET - ���ƴ�ֱ��
                 TFT_LCD_TYPE_CLR - �����ֱ��
                 TFT_LCD_TYPE_INV - ���Դ�ֱ��
����ֵ����
******************************************************************************/
void Original_TFT_LCD_Draw_Vertical_Line(uint16_t PosX, uint16_t StartY, uint16_t EndY, uint8_t Type)
{
  if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    return;
  
  if ((PosX   >= TFT_LCD_X_SIZE) || \
      (StartY >= TFT_LCD_Y_SIZE) || (EndY >= TFT_LCD_Y_SIZE))
    return;
    
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode            = TFT_LCD_MODE_VLINE;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ((uint8_t)(StartY >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        =  (uint8_t)PosX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = ((uint8_t)(EndY   >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          =  (uint8_t)PosX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;

  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Type            = Type;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ((uint8_t)(StartY & 0x0003));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftB       = ((uint8_t)(EndY   & 0x0003));
  
  if (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage > TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage + 1)
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_DRAW;
  else
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State         = TFT_LCD_STATE_VERTEX;
 
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0; 
}

void  TFT_LCD_Clean_FIFO_Ptr(void)
{
    /*uint8_t i;
    
    TFTLCDDrawingFIFO.Depth = 0;
    for (i = 0; i < TFT_LCD_REQ_FIFO_MAX_DEPTH; i++)
        TFTLCDDrawingFIFO.Req[i].Mode = TFT_LCD_MODE_IDLE;  */
} 

/******************************************************************************
��������TFT_LCD_Draw_Box
��  �ܣ���TFTҺ����ʾ��ָ��λ���ϻ��ƾ���
        ����ʹStartY����Ϊ8��������,ͬʱʹEndY����Ϊ8����������1,����߻�ͼ�ٶ�
        ȫ�������εĻ�ͼ�ٶȿ��ڲ�������
��  ����StartX - ��ͼ��ʼx����        
        StartY - ��ͼ��ʼy����
        EndX   - ��ͼ����x����
        EndY   - ��ͼ����y����
        Fill   - ���,������:
                 TFT_LCD_FILL_NONE - �����
                 TFT_LCD_FILL_FULL - ȫ�����
        Type   - ��ͼ����,������:
                 TFT_LCD_TYPE_SET - ���ƾ���
                 TFT_LCD_TYPE_CLR - �������
                 TFT_LCD_TYPE_INV - ���Ծ���
����ֵ����
******************************************************************************/
void Original_TFT_LCD_Draw_Box(uint16_t StartX, uint16_t StartY, uint16_t EndX, uint16_t EndY, uint8_t Fill, uint8_t Type)
{ 
  if (TFTLCDDrawingFIFO.Depth >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
  {
      //TFTLCDDrawingFIFO.Depth = 0;
       return;
   } 

  
  if ((StartX >= TFT_LCD_X_SIZE) || (EndX >= TFT_LCD_X_SIZE) ||\
      (StartY >= TFT_LCD_Y_SIZE) || (EndY >= TFT_LCD_Y_SIZE))
    return;
    
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage       = ((uint8_t)(StartY >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol        =  (uint8_t)StartX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage         = ((uint8_t)(EndY   >> 2));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol          =  (uint8_t)EndX;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentPage     = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].CurrentCol      = TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Width           = EndX - StartX + 1;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Length          = (((EndY - StartY + 1) >> 2) + 1) * TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Width;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Offset          = 0;
  
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Type            = Type;
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT       = ((uint8_t)(StartY & 0x0003));
  TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftB       = ((uint8_t)(EndY   & 0x0003));
  
  if (Fill)
  {
    if ((TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftT == 0x00) &&
        (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].BitShiftB == 0x03))
    {
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode        = TFT_LCD_MODE_DFBOX;
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State       = TFT_LCD_STATE_INIT; 
    }
    else
    {
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode        = TFT_LCD_MODE_IFBOX;
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State       = TFT_LCD_STATE_TOP;
    }
  }
  else
  {
    TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].Mode          = TFT_LCD_MODE_BBOX;
    if (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndCol > TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartCol + 1)
      TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State       = TFT_LCD_STATE_TOP;
    else
    {
      if (TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].EndPage > TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].StartPage + 1)
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State     = TFT_LCD_STATE_LEFT;
      else
        TFTLCDDrawingFIFO.Req[TFTLCDDrawingFIFO.Iptr].State     = TFT_LCD_STATE_VERTEX;
    }
  }
    
  //FIFO����
  TFTLCDDrawingFIFO.Depth++;
  TFTLCDDrawingFIFO.Iptr++;
  if (TFTLCDDrawingFIFO.Iptr >= TFT_LCD_REQ_FIFO_MAX_DEPTH)
    TFTLCDDrawingFIFO.Iptr = 0;
}

/******************************************************************************
��������TFT_LCD_Cls_Handler
��  �ܣ�[�ڲ�����]���TFTҺ����ʾ��ȫ����ʾִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Cls_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t i;
  uint8_t Rtn;
  
  Rtn = 0;
  switch (pReq -> State)
  {
    case TFT_LCD_STATE_INIT : LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              pReq -> State = TFT_LCD_STATE_DRAW;                              
                              break;
                              
    case TFT_LCD_STATE_DRAW : for (i = 0; i < 30; i++)
                                LCD_Write_Data(0x00);
                              
                              pReq -> Offset += 30;
                              if (pReq -> Offset >= pReq -> Length)
                              {
                                pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                              }
                              break;
                              
    default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                              Rtn = 1;
                              break;
  }
  
  return Rtn;
}

//ͼƬ��ѹ
static void Uncompress_Picture(uint16_t Pos,TFTLCDDrawingReqStruct *pReq)
{
   
    while(buff_array.arrayTotolPosCur <= Pos)
    {
      if(buff_array.arrayInPosCur == 0)
      {	      
    	  if(( pReq->pBmp[buff_array.arrayPosCur] == 0)||( pReq->pBmp[buff_array.arrayPosCur] == 0xff))
    	  {	 
    	    buff_array.arrayInPosCur = pReq->pBmp[buff_array.arrayPosCur + 1];
    	    buff_array.arrayPosCur += 2;
          }
    	  else
    	  {
    	    if(buff_array.arrayTotolPosCur == Pos)
    	    {
    	        //*BmpDat = pReq->pBmp[buff_array.arrayPosCur];
    	        pixelPointList.array[pixelPointList.Top_Pos] = pReq->pBmp[buff_array.arrayPosCur]; 
    	       	            
	            pixelPointList.End_Pos = pixelPointList.Top_Pos;
	            pixelPointList.Top_Pos++;
                if(pixelPointList.Top_Pos > pReq->Width)
    	        {
    	            pixelPointList.Top_Pos = 0;  
    	        } 
	          
    	    }        	     	    
    	    buff_array.arrayTotolPosCur++;       
    	    buff_array.arrayPosCur++;       	 	
    	  }	    	  
      }
      else
      {
          if(buff_array.arrayTotolPosCur == Pos)
          {
             //*BmpDat =  pReq->pBmp[buff_array.arrayPosCur - 2];
  	         pixelPointList.array[pixelPointList.Top_Pos] = pReq->pBmp[buff_array.arrayPosCur - 2];
  	        
  	         pixelPointList.End_Pos = pixelPointList.Top_Pos;
  	         pixelPointList.Top_Pos++;
             if(pixelPointList.Top_Pos > pReq->Width)
  	         {	          
  	            pixelPointList.Top_Pos = 0;  
  	         }
	         
          }                  
          buff_array.arrayTotolPosCur++;            
          buff_array.arrayInPosCur--;            
      }	   
    }
}

/******************************************************************************
��������TFT_LCD_Direct_Draw_Bmp_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ����ֱ�ӻ��Ʋ�͸��λͼִ�к���
        ��λͼ������ʼY����Ϊ8��������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Direct_Draw_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   ColInc;
  uint8_t   Bmp_tmp;
  uint8_t   Bmp_tmp1;
  Rtn = 0;
  switch (pReq -> State)
  {
    case TFT_LCD_STATE_INIT : LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              pReq -> State = TFT_LCD_STATE_DRAW;                              
                              break;
                              
    case TFT_LCD_STATE_DRAW : if (pReq -> Length - pReq -> Offset > 30)
                                ColInc = 30;
                              else
                                ColInc = (uint8_t)(pReq -> Length - pReq -> Offset);
                                
                              for (i = 0; i < ColInc; i++)
                              {  
                                //ѹ��                            
                                if(pReq -> IsCompress == 0)
                                    Bmp_tmp = pReq -> pBmp[pReq -> Offset];
                                    //LCD_Write_Data();
                                else
                                {                                   
                                    Uncompress_Picture(pReq -> Offset,pReq);
                                    Bmp_tmp = pixelPointList.array[pixelPointList.End_Pos];                                
                                }
                                //��ת
                                if(pReq -> IsInverse == 1)
                                {
                                   Bmp_tmp = 0xFF - Bmp_tmp;
                                }                               
                                LCD_Write_Data(Bmp_tmp);                                                     
                                pReq -> Offset++;
                              }
                                
                              if (pReq -> Offset >= pReq -> Length)
                              {
                                pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                              }
                              break;
                              
    default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                              Rtn = 1;
                              break;
  }

  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Direct_Draw_Bmp_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ����ֱ�ӻ��Ʋ�͸��λͼִ�к���
        ��λͼ������ʼY����Ϊ8��������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Direct_Draw_Bmp_TEST(TFTLCDDrawingReqStruct *pReq)
{
          
    //test_buff_commit(&KK,AA,pReq);
     return 0;
}

/******************************************************************************
��������TFT_LCD_Insert_Draw_Bmp_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϲ��벻͸��λͼִ�к���
        ��λͼ������ʼY���겻Ϊ8��������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/

static uint8_t TFT_LCD_Insert_Draw_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   BmpDat[sizeofLCD];
  uint8_t   ColInc;
  uint8_t   ShiftL;
  uint8_t   ShiftR;
  uint8_t   Mask;
  uint16_t  IndexH;
  uint16_t  IndexL;
  uint8_t   Bmp_temp;

  Rtn = 0;
  switch (pReq -> State)
  {                       
    case TFT_LCD_STATE_TOP  : //��ҳͼƬ��Ҫ����ԭ����������ƴ��
                              //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ  ����������
                              ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                              if (ColInc > sizeofLCD)
                                ColInc = sizeofLCD;
                              
                              ShiftL  = pReq -> BitShiftT * 2;
                              Mask    = TFTLCDBitMask[pReq -> BitShiftT];
                                  
                              //����ԭ��������
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Reading();
                              BmpDat[0] = LCD_Read_Data();      //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                              
                              for (i = 0; i < ColInc; i++)
                                BmpDat[i] = LCD_Read_Data() & Mask;
                                  
                              //ƴ�Ӳ���д����
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              
                              for (i = 0; i < ColInc; i++)
                              {
                                IndexH = pReq -> Offset + (uint16_t)i;
                                
                                if(pReq -> IsCompress == 0)
                                { 
                                    Bmp_temp = pReq -> pBmp[IndexH];                                 
                                    //BmpDat[i] |= pReq -> pBmp[IndexH] << ShiftL;
                                }
                                else
                                {
                                   Uncompress_Picture(IndexH,pReq);
                                   Bmp_temp = pixelPointList.array[pixelPointList.End_Pos];                                  
                                }
                                //��ת
                                if(pReq -> IsInverse == 1)
                                   Bmp_temp = 0xFF - Bmp_temp;
                                 
                                BmpDat[i] |= Bmp_temp << ShiftL;
                                
                                LCD_Write_Data(BmpDat[i]);
                              }
                              
                              pReq -> Offset     += ColInc;
                              pReq -> CurrentCol += ColInc;
                                
                              if (pReq -> CurrentCol > pReq -> EndCol)
                              {
                                pReq -> CurrentCol = pReq -> StartCol;
                                pReq -> CurrentPage++;
                                
                                if (pReq -> CurrentPage >= pReq -> EndPage)
                                  pReq -> State = TFT_LCD_STATE_BOT;
                                else
                                {
                                  //��ҳ���ݿ�������д��
                                  LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  pReq -> State = TFT_LCD_STATE_MID;
                                }
                              }
                              break;
                              
    case TFT_LCD_STATE_MID  : //��ҳͼƬ�������ԭ��������
                              //ֻ��Ҫ��д��ͼƬ��������ƴ��д�����ϼ���
                              ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                              if (ColInc > sizeofLCD)
                                ColInc = sizeofLCD;
                              
                              ShiftL  = pReq -> BitShiftT * 2;
                              ShiftR  = ((4 - pReq -> BitShiftT) * 2 ) & 0x07;
                              
                              for (i = 0; i < ColInc; i++)
                              {
                                IndexH = pReq -> Offset + (uint16_t)i;
                                IndexL = IndexH - pReq -> Width;
                                if(pReq -> IsCompress == 0)
                                {
                                    BmpDat[0]  = pReq -> pBmp[IndexH] << ShiftL;
                                    BmpDat[0] |= pReq -> pBmp[IndexL] >> ShiftR;
                                }
                                else
                                {
                                    Uncompress_Picture(IndexH,pReq);
                                    Bmp_temp = pixelPointList.array[pixelPointList.End_Pos];
                                    BmpDat[0]  = Bmp_temp << ShiftL;
                                    
                                    Bmp_temp = pixelPointList.array[pixelPointList.Top_Pos];
                                    BmpDat[0] |= Bmp_temp >> ShiftR;
                                }
                                
                                //��ת
                                if(pReq -> IsInverse == 1)
                                {
                                   Bmp_temp = 0xFF - BmpDat[0];
                                } 
                                else
                                   Bmp_temp = BmpDat[0];                       
                                
                                LCD_Write_Data(Bmp_temp);
                              }                   
                              
                              pReq -> Offset     += ColInc;
                              pReq -> CurrentCol += ColInc;
                                
                              if (pReq -> CurrentCol > pReq -> EndCol)
                              {
                                pReq -> CurrentCol = pReq -> StartCol;
                                pReq -> CurrentPage++;
                                
                                if (pReq -> CurrentPage >= pReq -> EndPage)
                                  pReq -> State = TFT_LCD_STATE_BOT;
                              }
                              break;
                              
    case TFT_LCD_STATE_BOT  : //βҳͼƬ��Ҫ����ԭ����������ƴ��
                              //��д��ͼƬ���ݵĵ�λȡ��ƴ����ԭ�������ݵĸ�λ
                              ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                              if (ColInc > sizeofLCD)
                                ColInc = sizeofLCD;                      
                                                                
                              ShiftR  = ((4 - pReq -> BitShiftT) * 2 ) & 0x07;
                              Mask    = ~TFTLCDBitMask[pReq -> BitShiftT];
                              
                              //����ԭ��������
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Reading();
                              BmpDat[0] = LCD_Read_Data();      //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                              
                              for (i = 0; i < ColInc; i++)
                                BmpDat[i] = LCD_Read_Data() & Mask;
                              
                              //ƴ�Ӳ���д����
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              
                              for (i = 0; i < ColInc; i++)
                              {
                                IndexL = pReq -> Offset - pReq -> Width + (uint16_t)i;                             
                                if(pReq -> IsCompress == 0)
                                {
                                    Bmp_temp = pReq -> pBmp[IndexL];
                                    //BmpDat[i] |= pReq -> pBmp[IndexL] >> ShiftR;
                                }
                                else
                                {
                                    Uncompress_Picture(pReq -> Offset + i,pReq);
                                    Bmp_temp = pixelPointList.array[pixelPointList.Top_Pos];                                                                                                    
                                } 
                                
                                //��ת
                                if(pReq -> IsInverse == 1)
                                   Bmp_temp = 0xFF - Bmp_temp;                                 
                                BmpDat[i] |= Bmp_temp >> ShiftR;                                                                                 
                                LCD_Write_Data(BmpDat[i]);
                              }
                              
                              pReq -> Offset     += ColInc;
                              pReq -> CurrentCol += ColInc;
                                
                              if (pReq -> CurrentCol > pReq -> EndCol)
                              {
                                pReq -> CurrentCol = pReq -> StartCol;
                                pReq -> CurrentPage++;
                                
                                if (pReq -> CurrentPage > pReq -> EndPage)
                                {
                                  pReq -> State = TFT_LCD_STATE_IDLE;
                                  Rtn = 1;
                                }
                              }
                              break;
                              
    default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                              Rtn = 1;
                              break;
  }

  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Direct_Draw_Transparent_Bmp_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ����ֱ�ӻ���͸��λͼִ�к���
        ��λͼ������ʼY����Ϊ8��������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Direct_Draw_Transparent_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   BmpDat[sizeofLCD];
  uint8_t   ColInc;
  
  if (pReq -> State != TFT_LCD_STATE_DRAW)
  {
    pReq -> State = TFT_LCD_STATE_IDLE;
    return 1;
  }
  
  Rtn = 0;
  ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
  if (ColInc > sizeofLCD)
    ColInc = sizeofLCD;
  
  //����ԭ��������
  LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
  LCD_Start_Data_Reading();
  BmpDat[0] = LCD_Read_Data();      //�����ĵ�һ���ֽ�Ϊ��Ч����,����
  
  for (i = 0; i < ColInc; i++)
    BmpDat[i] = LCD_Read_Data();
      
  //ƴ�Ӳ���д����
  LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
  LCD_Start_Data_Writing();
  
  if (pReq -> Type == TFT_LCD_TYPE_CLR)
  {
    for (i = 0; i < ColInc; i++)
    {
      BmpDat[i] &= ~(pReq -> pBmp[pReq -> Offset]);
      LCD_Write_Data(BmpDat[i]);
      pReq -> Offset++;
    }
  }
  else if (pReq -> Type == TFT_LCD_TYPE_INV)
  {
    for (i = 0; i < ColInc; i++)
    {
      BmpDat[i] ^= pReq -> pBmp[pReq -> Offset];
      LCD_Write_Data(BmpDat[i]);
      pReq -> Offset++;
    }
  }
  else
  {
    for (i = 0; i < ColInc; i++)
    {
      BmpDat[i] |= pReq -> pBmp[pReq -> Offset];
      LCD_Write_Data(BmpDat[i]);
      pReq -> Offset++;
    }
  }
  
  pReq -> CurrentCol += ColInc;
    
  if (pReq -> CurrentCol > pReq -> EndCol)
  {
    pReq -> CurrentCol = pReq -> StartCol;
    pReq -> CurrentPage++;
    
    if (pReq -> CurrentPage > pReq -> EndPage)
    {
      pReq -> State = TFT_LCD_STATE_IDLE;
      Rtn = 1;
    }
  }
  
  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Insert_Draw_Transparent_Bmp_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϲ���͸��λͼִ�к���
        ��λͼ������ʼY���겻Ϊ8��������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Insert_Draw_Transparent_Bmp_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   Mask;
  uint8_t   BmpDat[sizeofLCD];
  uint8_t   ColInc;
  uint8_t   ShiftL;
  uint8_t   ShiftR;
  uint16_t  IndexH;
  uint16_t  IndexL;
  
  Rtn = 0;
  
  ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
  if (ColInc > sizeofLCD)
    ColInc = sizeofLCD;
  
  //����ԭ��������
  LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
  LCD_Start_Data_Reading();
  BmpDat[0] = LCD_Read_Data();      //�����ĵ�һ���ֽ�Ϊ��Ч����,����
  
  for (i = 0; i < ColInc; i++)
    BmpDat[i] = LCD_Read_Data();
      
  //ƴ�Ӳ���д����
  LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
  LCD_Start_Data_Writing();
  
  switch (pReq -> State)
  {
    case TFT_LCD_STATE_TOP  : ShiftL  = pReq -> BitShiftT * 2;
    
                              if (pReq -> Type == TFT_LCD_TYPE_CLR)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  BmpDat[i] &= ~(pReq -> pBmp[IndexH] << ShiftL);
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  BmpDat[i] ^= (pReq -> pBmp[IndexH] << ShiftL);
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  BmpDat[i] |= pReq -> pBmp[IndexH] << ShiftL;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              break;
                              
    case TFT_LCD_STATE_MID  : ShiftL  = pReq -> BitShiftT *2 ;
                              ShiftR  = ((4 - pReq -> BitShiftT) *2 ) & 0x07;
                              
                              if (pReq -> Type == TFT_LCD_TYPE_CLR)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  IndexL = IndexH - pReq -> Width;
                                  
                                  Mask       = pReq -> pBmp[IndexH] << ShiftL | pReq -> pBmp[IndexL] >> ShiftR;
                                  BmpDat[i] &= ~Mask;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  IndexL = IndexH - pReq -> Width;
                                  
                                  Mask       = pReq -> pBmp[IndexH] << ShiftL | pReq -> pBmp[IndexL] >> ShiftR;
                                  BmpDat[i] ^= Mask;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexH = pReq -> Offset + (uint16_t)i;
                                  IndexL = IndexH - pReq -> Width;
                                  
                                  Mask       = pReq -> pBmp[IndexH] << ShiftL | pReq -> pBmp[IndexL] >> ShiftR;
                                  BmpDat[i] |= Mask;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              break;
                              
    case TFT_LCD_STATE_BOT  : ShiftR  = ((4 - pReq -> BitShiftT) * 2 ) & 0x07;
                              
                              if (pReq -> Type == TFT_LCD_TYPE_CLR)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexL = pReq -> Offset - pReq -> Width + (uint16_t)i;
                                  BmpDat[i] &= ~(pReq -> pBmp[IndexL] >> ShiftR);
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexL = pReq -> Offset - pReq -> Width + (uint16_t)i;
                                  BmpDat[i] ^= pReq -> pBmp[IndexL] >> ShiftR;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              else
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  IndexL = pReq -> Offset - pReq -> Width + (uint16_t)i;
                                  BmpDat[i] |= pReq -> pBmp[IndexL] >> ShiftR;
                                  LCD_Write_Data(BmpDat[i]);
                                }
                              }
                              break;
                              
    default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                              return 1;
                              break;
  }
  
  pReq -> Offset     += ColInc;
  pReq -> CurrentCol += ColInc;
    
  if (pReq -> CurrentCol > pReq -> EndCol)
  {
    pReq -> CurrentCol = pReq -> StartCol;
    pReq -> CurrentPage++;
    
    if (pReq -> CurrentPage < pReq -> EndPage)
      pReq -> State = TFT_LCD_STATE_MID;
    else if (pReq -> CurrentPage == pReq -> EndPage)
      pReq -> State = TFT_LCD_STATE_BOT;
    else
    {
      pReq -> State = TFT_LCD_STATE_IDLE;
      return 1;
    }
  }
  
  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Draw_Pixel_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϻ������ص�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Draw_Pixel_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   DispData;
  
  if (pReq -> State == TFT_LCD_STATE_DRAW)
  {
    //����ԭ��������
    LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> EndCol, pReq -> EndPage);
    LCD_Start_Data_Reading();
    DispData = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
    DispData = LCD_Read_Data();
    
    if (pReq -> Type == TFT_LCD_TYPE_CLR)
      DispData &= ~TFTLCDBitTable[pReq -> BitShiftT];
    else if  (pReq -> Type == TFT_LCD_TYPE_INV)
      DispData ^=  TFTLCDBitTable[pReq -> BitShiftT];
    else
      DispData |=  TFTLCDBitTable[pReq -> BitShiftT];
    
    //��д����
    LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> EndCol, pReq -> EndPage);
    LCD_Start_Data_Writing();
    LCD_Write_Data(DispData);
  }
  
  pReq -> State = TFT_LCD_STATE_IDLE;
  return 1;
}

/******************************************************************************
��������TFT_LCD_Draw_Horizontal_Line_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϻ���ˮƽ��ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Draw_Horizontal_Line_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   ColInc;
  uint8_t   Mask;
  uint8_t   DispData[10];
  
  if (pReq -> State != TFT_LCD_STATE_DRAW)
  {
    pReq -> State = TFT_LCD_STATE_IDLE;
    return 1;
  }

  Mask = TFTLCDBitTable[pReq -> BitShiftT];
  ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
  if (ColInc > 10)
    ColInc = 10;

  //����ԭ��������
  LCD_Set_Window(pReq -> CurrentCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
  LCD_Start_Data_Reading();
  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
    
  for (i = 0; i < ColInc; i++)
    DispData[i] = LCD_Read_Data();
  
  //��������д����
  LCD_Set_Window(pReq -> CurrentCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
  LCD_Start_Data_Writing();
  
  if (pReq -> Type == TFT_LCD_TYPE_CLR)
  {
    for (i = 0; i < ColInc; i++)
    {
      DispData[i] &= ~Mask;
      LCD_Write_Data(DispData[i]);
    }
  }
  else if (pReq -> Type == TFT_LCD_TYPE_INV)
  {
    for (i = 0; i < ColInc; i++)
    {
      DispData[i] ^= Mask;
      LCD_Write_Data(DispData[i]);
    }
  }
  else
  {
    for (i = 0; i < ColInc; i++)
    {
      DispData[i] |= Mask;
      LCD_Write_Data(DispData[i]);
    }
  }

  pReq -> CurrentCol += ColInc;
                                    
  if (pReq -> CurrentCol > pReq -> EndCol)
  {
    pReq -> State = TFT_LCD_STATE_IDLE;
    return 1;
  }
  
  return 0;
}

/******************************************************************************
��������TFT_LCD_Draw_Horizontal_Line_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϻ��ƴ�ֱ��ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Draw_Vertical_Line_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   PageInc;
  uint8_t   Mask;
  uint8_t   DispData[10];
  
  Rtn = 0;
  switch (pReq -> State)
  {
    case TFT_LCD_STATE_DRAW   : pReq -> CurrentPage += 1;
                                PageInc = pReq -> EndPage - pReq -> CurrentPage;
                                
                                if (pReq -> Type == TFT_LCD_TYPE_INV)
                                {
                                  if (PageInc > 10)
                                    PageInc = 10;
                                  
                                  //����ԭ��������
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                    
                                  for (i = 0; i < PageInc; i++)
                                    DispData[i] = LCD_Read_Data();
                                    
                                  //��������д����
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  for (i = 0; i < PageInc; i++)
                                    LCD_Write_Data(~DispData[i]);
                                }
                                else
                                {
                                  if (PageInc > 30)
                                    PageInc = 30;
                                  
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                  {
                                    for (i = 0; i < PageInc; i++)
                                      LCD_Write_Data(0x00);
                                  }
                                  else
                                  {
                                    for (i = 0; i < PageInc; i++)
                                      LCD_Write_Data(0xFF);
                                  }
                                }
                                
                                pReq -> CurrentPage += PageInc;
                                    
                                if (pReq -> CurrentPage >= pReq -> EndPage)
                                  pReq -> State = TFT_LCD_STATE_VERTEX;
                                break;
                                
    case TFT_LCD_STATE_VERTEX : if (pReq -> StartPage == pReq -> EndPage)
                                  Mask = ~TFTLCDBitMask[pReq -> BitShiftT] & TFTLCDBitMask[pReq -> BitShiftB + 1];
                                else
                                  Mask = ~TFTLCDBitMask[pReq -> BitShiftT];
                                
                                LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> StartCol, pReq -> StartPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                DispData[0] = LCD_Read_Data();
                                    
                                //��������д����
                                LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> StartCol, pReq -> StartPage);
                                LCD_Start_Data_Writing();
                                
                                if (pReq -> Type == TFT_LCD_TYPE_INV)
                                  LCD_Write_Data(DispData[0] ^ Mask);
                                else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                  LCD_Write_Data(DispData[0] & ~Mask);
                                else
                                  LCD_Write_Data(DispData[0] | Mask);
                                
                                if (pReq -> StartPage != pReq -> EndPage)
                                {
                                  Mask = TFTLCDBitMask[pReq -> BitShiftB + 1];
                                  
                                  LCD_Set_Window(pReq -> StartCol, pReq -> EndPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                  DispData[0] = LCD_Read_Data();
                                      
                                  //��������д����
                                  LCD_Set_Window(pReq -> StartCol, pReq -> EndPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_INV)
                                    LCD_Write_Data(DispData[0] ^ Mask);
                                  else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                    LCD_Write_Data(DispData[0] & ~Mask);
                                  else
                                    LCD_Write_Data(DispData[0] | Mask);
                                }
                                
                                pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
                                
    default                   : pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
  }
  
  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Draw_Box_Border_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϻ��ƾ��α߿�ִ�к���
        ��������Ʋ�������ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Draw_Box_Border_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   Inc;
  uint8_t   Mask;
  uint8_t   DispData[10];
  
  Rtn = 0;
  switch (pReq -> State)
  {
    case TFT_LCD_STATE_TOP    : if (pReq -> StartPage == pReq -> EndPage)
                                  Mask = TFTLCDBitTable[pReq -> BitShiftT] | TFTLCDBitTable[pReq -> BitShiftB];
                                else
                                  Mask = TFTLCDBitTable[pReq -> BitShiftT];
                                
                                //��ˮƽ��ʱ�������Ҷ���,���Ҷ���������
                                pReq -> CurrentCol += 1;
                                Inc = pReq -> EndCol - pReq -> CurrentCol;
                                if (Inc > 10)
                                  Inc = 10;
                                  
                                //����ԭ��������
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                  
                                for (i = 0; i < Inc; i++)
                                  DispData[i] = LCD_Read_Data();
                                  
                                //��������д����
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
                                LCD_Start_Data_Writing();
                                
                                if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] &= ~Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                else if (pReq -> Type == TFT_LCD_TYPE_INV)
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] ^= Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                else
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] |= Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                
                                pReq -> CurrentCol += Inc;
                                    
                                if (pReq -> CurrentCol >= pReq -> EndCol)
                                {
                                  if (pReq -> StartPage == pReq -> EndPage)
                                  {
                                    if (pReq -> EndPage > pReq -> StartPage + 1)
                                      pReq -> State = TFT_LCD_STATE_LEFT;
                                    else
                                      pReq -> State = TFT_LCD_STATE_VERTEX;
                                  }
                                  else
                                  {
                                    pReq -> CurrentCol  = pReq -> StartCol + 1;
                                    pReq -> State = TFT_LCD_STATE_BOT;
                                  }
                                }
                                break;
                              
    case TFT_LCD_STATE_BOT    : Mask = TFTLCDBitTable[pReq -> BitShiftB];
                              
                                Inc = pReq -> EndCol - pReq -> CurrentCol;
                                if (Inc > 10)
                                  Inc = 10;
                                  
                                //����ԭ��������
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> EndPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                  
                                for (i = 0; i < Inc; i++)
                                  DispData[i] = LCD_Read_Data();
                                  
                                //��������д����
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> EndPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Writing();
                                
                                if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] &= ~Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                else if (pReq -> Type == TFT_LCD_TYPE_INV)
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] ^= Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                else
                                {
                                  for (i = 0; i < Inc; i++)
                                  {
                                    DispData[i] |= Mask;
                                    LCD_Write_Data(DispData[i]);
                                  }
                                }
                                
                                pReq -> CurrentCol += Inc;
                                    
                                if (pReq -> CurrentCol >= pReq -> EndCol)
                                {
                                  if (pReq -> EndPage > pReq -> StartPage + 1)
                                    pReq -> State = TFT_LCD_STATE_LEFT;
                                  else
                                    pReq -> State = TFT_LCD_STATE_VERTEX;
                                }
                                break;                              
                                
    case TFT_LCD_STATE_LEFT   : //����ֱ��ʱ�������¶���,���¶���������
                                pReq -> CurrentPage += 1;
                                Inc = pReq -> EndPage - pReq -> CurrentPage;
                                
                                if (pReq -> Type == TFT_LCD_TYPE_INV)
                                {
                                  if (Inc > 10)
                                    Inc = 10;
                                  
                                  //����ԭ��������
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                    
                                  for (i = 0; i < Inc; i++)
                                    DispData[i] = LCD_Read_Data();
                                    
                                  //��������д����
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  for (i = 0; i < Inc; i++)
                                    LCD_Write_Data(~DispData[i]);
                                }
                                else
                                {
                                  if (Inc > 30)
                                    Inc = 30;
                                  
                                  LCD_Set_Window(pReq -> StartCol, pReq -> CurrentPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                  {
                                    for (i = 0; i < Inc; i++)
                                      LCD_Write_Data(0x00);
                                  }
                                  else
                                  {
                                    for (i = 0; i < Inc; i++)
                                      LCD_Write_Data(0xFF);
                                  }
                                }
                               
                                pReq -> CurrentPage += Inc;
                                    
                                if (pReq -> CurrentPage >= pReq -> EndPage)
                                {
                                  if (pReq -> StartCol == pReq -> EndCol)
                                    pReq -> State = TFT_LCD_STATE_VERTEX;
                                  else
                                  {
                                    pReq -> CurrentPage  = pReq -> StartPage + 1;
                                    pReq -> State = TFT_LCD_STATE_RIGHT;
                                  }
                                }
                                break;                              
                                
    case TFT_LCD_STATE_RIGHT  : //����ֱ��ʱ�������¶���,���¶���������
                                Inc = pReq -> EndPage - pReq -> CurrentPage;
                                
                                if (pReq -> Type == TFT_LCD_TYPE_INV)
                                {
                                  if (Inc > 10)
                                    Inc = 10;
                                  
                                  //����ԭ��������
                                  LCD_Set_Window(pReq -> EndCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                    
                                  for (i = 0; i < Inc; i++)
                                    DispData[i] = LCD_Read_Data();
                                    
                                  //��������д����
                                  LCD_Set_Window(pReq -> EndCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  for (i = 0; i < Inc; i++)
                                    LCD_Write_Data(~DispData[i]);
                                }
                                else
                                {
                                  if (Inc > 30)
                                    Inc = 30;
                                  
                                  LCD_Set_Window(pReq -> EndCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                  {
                                    for (i = 0; i < Inc; i++)
                                      LCD_Write_Data(0x00);
                                  }
                                  else
                                  {
                                    for (i = 0; i < Inc; i++)
                                      LCD_Write_Data(0xFF);
                                  }
                                }
                               
                                pReq -> CurrentPage += Inc;
                                    
                                if (pReq -> CurrentPage >= pReq -> EndPage)
                                  pReq -> State = TFT_LCD_STATE_VERTEX;
                                break; 
                                
    case TFT_LCD_STATE_VERTEX : if (pReq -> StartPage == pReq -> EndPage)
                                  Mask = ~TFTLCDBitMask[pReq -> BitShiftT] & TFTLCDBitMask[pReq -> BitShiftB + 1];
                                else
                                  Mask = ~TFTLCDBitMask[pReq -> BitShiftT];
                                
                                LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> StartCol, pReq -> StartPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                DispData[0] = LCD_Read_Data();
                                    
                                //��������д����
                                LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> StartCol, pReq -> StartPage);
                                LCD_Start_Data_Writing();
                                
                                if (pReq -> Type == TFT_LCD_TYPE_INV)
                                  LCD_Write_Data(DispData[0] ^ Mask);
                                else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                  LCD_Write_Data(DispData[0] & ~Mask);
                                else
                                  LCD_Write_Data(DispData[0] | Mask);
                                
                                if (pReq -> StartPage != pReq -> EndPage)
                                {
                                  Mask = TFTLCDBitMask[pReq -> BitShiftB + 1];
                                  
                                  LCD_Set_Window(pReq -> StartCol, pReq -> EndPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                  DispData[0] = LCD_Read_Data();
                                      
                                  //��������д����
                                  LCD_Set_Window(pReq -> StartCol, pReq -> EndPage, pReq -> StartCol, pReq -> EndPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_INV)
                                    LCD_Write_Data(DispData[0] ^ Mask);
                                  else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                    LCD_Write_Data(DispData[0] & ~Mask);
                                  else
                                    LCD_Write_Data(DispData[0] | Mask);
                                }
                                
                                if (pReq -> StartCol != pReq -> EndCol)
                                {
                                  if (pReq -> StartPage == pReq -> EndPage)
                                    Mask = ~TFTLCDBitMask[pReq -> BitShiftT] & TFTLCDBitMask[pReq -> BitShiftB + 1];
                                  else
                                    Mask = ~TFTLCDBitMask[pReq -> BitShiftT];
                                  
                                  LCD_Set_Window(pReq -> EndCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
                                  LCD_Start_Data_Reading();
                                  DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                  DispData[0] = LCD_Read_Data();
                                      
                                  //��������д����
                                  LCD_Set_Window(pReq -> EndCol, pReq -> StartPage, pReq -> EndCol, pReq -> StartPage);
                                  LCD_Start_Data_Writing();
                                  
                                  if (pReq -> Type == TFT_LCD_TYPE_INV)
                                    LCD_Write_Data(DispData[0] ^ Mask);
                                  else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                    LCD_Write_Data(DispData[0] & ~Mask);
                                  else
                                    LCD_Write_Data(DispData[0] | Mask);
                                  
                                  if (pReq -> StartPage != pReq -> EndPage)
                                  {
                                    Mask = TFTLCDBitMask[pReq -> BitShiftB + 1];
                                    
                                    LCD_Set_Window(pReq -> EndCol, pReq -> EndPage, pReq -> EndCol, pReq -> EndPage);
                                    LCD_Start_Data_Reading();
                                    DispData[0] = LCD_Read_Data();       //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                    DispData[0] = LCD_Read_Data();
                                        
                                    //��������д����
                                    LCD_Set_Window(pReq -> EndCol, pReq -> EndPage, pReq -> EndCol, pReq -> EndPage);
                                    LCD_Start_Data_Writing();
                                    
                                    if (pReq -> Type == TFT_LCD_TYPE_INV)
                                      LCD_Write_Data(DispData[0] ^ Mask);
                                    else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                      LCD_Write_Data(DispData[0] & ~Mask);
                                    else
                                      LCD_Write_Data(DispData[0] | Mask);
                                  }
                                }
                                
                                pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
                                
    default                   : pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
  }

  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Direct_Draw_Full_Box_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ����ֱ�ӻ���������ִ�к���
        ���������ȫ��������,����ʼy����Ϊ8��������,����y����Ϊ8����������1ʱ
        ʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Direct_Draw_Full_Box_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   ColInc;
  uint8_t   DispData[10];
  
  Rtn = 0;
  if (pReq -> Type == TFT_LCD_TYPE_INV)
  {
    switch (pReq -> State)
    {
      case TFT_LCD_STATE_INIT : pReq -> State = TFT_LCD_STATE_DRAW;
      case TFT_LCD_STATE_DRAW : ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                                if (ColInc > 10)
                                  ColInc = 10;
                                
                                //����ԭ��������
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();      //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                
                                for (i = 0; i < ColInc; i++)
                                  DispData[i] = LCD_Read_Data();
                                
                                //��ת����д����
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Writing();
                                
                                for (i = 0; i < ColInc; i++)
                                  LCD_Write_Data(~DispData[i]);
                                
                                pReq -> CurrentCol += ColInc;
                                  
                                if (pReq -> CurrentCol > pReq -> EndCol)
                                {
                                  pReq -> CurrentCol = pReq -> StartCol;
                                  pReq -> CurrentPage++;
                                  
                                  if (pReq -> CurrentPage > pReq -> EndPage)
                                  {
                                    pReq -> State = TFT_LCD_STATE_IDLE;
                                    Rtn = 1;
                                  }
                                }
                                break;
                                
      default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
    }
  }
  else
  {
    switch (pReq -> State)
    {
      case TFT_LCD_STATE_INIT : LCD_Set_Window(pReq -> StartCol, pReq -> StartPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Writing();
                                pReq -> State = TFT_LCD_STATE_DRAW;                              
                                break;
                                
      case TFT_LCD_STATE_DRAW : if (pReq -> Length - pReq -> Offset > 30)
                                  ColInc = 30;
                                else
                                  ColInc = (uint8_t)(pReq -> Length - pReq -> Offset);
                                
                                if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                {
                                  for (i = 0; i < ColInc; i++)
                                  {
                                    LCD_Write_Data(0x00);
                                    pReq -> Offset++;
                                  }
                                }
                                else
                                {
                                  for (i = 0; i < ColInc; i++)
                                  {
                                    LCD_Write_Data(0xFF);
                                    pReq -> Offset++;
                                  }
                                }
                                  
                                if (pReq -> Offset >= pReq -> Length)
                                {
                                  pReq -> State = TFT_LCD_STATE_IDLE;
                                  Rtn = 1;
                                }
                                break;
                                
      default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                                Rtn = 1;
                                break;
    }
  }

  return Rtn;
}

/******************************************************************************
��������TFT_LCD_Insert_Draw_Full_Box_Handler
��  �ܣ�[�ڲ�����]��TFTҺ����ʾ���ϲ���������ִ�к���
        ���������ȫ��������,����ʼy���겻Ϊ8��������,�����y���겻Ϊ8������
        ����1ʱʹ�ô�ִ�к���
��  ����pReq - ��ͼ����
����ֵ��0 - ������
        1 - ���ƽ���
******************************************************************************/
static uint8_t TFT_LCD_Insert_Draw_Full_Box_Handler(TFTLCDDrawingReqStruct *pReq)
{
  uint8_t   i;
  uint8_t   Rtn;
  uint8_t   DispData[10];
  uint8_t   ColInc;
  uint8_t   Mask;
  
  Rtn = 0;
  switch (pReq -> State)
  {                       
    case TFT_LCD_STATE_TOP  : ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                              if (ColInc > 10)
                                ColInc = 10;
                              
                              if (pReq -> StartPage == pReq -> EndPage)
                                Mask = TFTLCDBitMask[pReq -> BitShiftT] | (~TFTLCDBitMask[pReq -> BitShiftB + 1]);
                              else
                                Mask = TFTLCDBitMask[pReq -> BitShiftT];
                                    
                              //����ԭ��������
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Reading();
                              DispData[0] = LCD_Read_Data();    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                              
                              for (i = 0; i < ColInc; i++)
                                DispData[i] = LCD_Read_Data();
                                  
                              //ƴ�Ӳ���д����
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              
                              if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] ^= ~Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] &= Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              else
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] |= ~Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              
                              pReq -> Offset     += ColInc;
                              pReq -> CurrentCol += ColInc;
                                
                              if (pReq -> CurrentCol > pReq -> EndCol)
                              {
                                pReq -> CurrentCol = pReq -> StartCol;
                                pReq -> CurrentPage++;
                                
                                if (pReq -> CurrentPage > pReq -> EndPage)
                                {
                                  pReq -> State = TFT_LCD_STATE_IDLE;
                                  Rtn = 1;
                                }
                                else if (pReq -> CurrentPage == pReq -> EndPage)
                                  pReq -> State = TFT_LCD_STATE_BOT;
                                else
                                {
                                  if (pReq -> Type != TFT_LCD_TYPE_INV)
                                  {
                                    LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                    LCD_Start_Data_Writing();
                                  }
                                  pReq -> State = TFT_LCD_STATE_MID;
                                }
                              }
                              break;
                              
    case TFT_LCD_STATE_MID  : if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                                if (ColInc > 10)
                                  ColInc = 10;
                                
                                //����ԭ��������
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Reading();
                                DispData[0] = LCD_Read_Data();  //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                                
                                for (i = 0; i < ColInc; i++)
                                  DispData[i] = LCD_Read_Data();
                                
                                //��ת����д����
                                LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                                LCD_Start_Data_Writing();
                                
                                for (i = 0; i < ColInc; i++)
                                  LCD_Write_Data(~DispData[i]);
                                
                                pReq -> Offset     += ColInc;
                                pReq -> CurrentCol += ColInc;
                                  
                                if (pReq -> CurrentCol > pReq -> EndCol)
                                {
                                  pReq -> CurrentCol = pReq -> StartCol;
                                  pReq -> CurrentPage++;
                                  
                                  if (pReq -> CurrentPage >= pReq -> EndPage)
                                    pReq -> State = TFT_LCD_STATE_BOT;
                                }
                              }
                              else
                              {
                                if (pReq -> Length - pReq -> Width - pReq -> Offset > 30)
                                  ColInc = 30;
                                else
                                  ColInc = (uint8_t)(pReq -> Length - pReq -> Width - pReq -> Offset);
                                
                                if (pReq -> Type == TFT_LCD_TYPE_CLR)
                                {
                                  for (i = 0; i < ColInc; i++)
                                  {
                                    LCD_Write_Data(0x00);
                                    pReq -> Offset++;
                                  }
                                }
                                else
                                {
                                  for (i = 0; i < ColInc; i++)
                                  {
                                    LCD_Write_Data(0xFF);
                                    pReq -> Offset++;
                                  }
                                }
                                  
                                if (pReq -> Offset >= pReq -> Length - pReq -> Width)
                                {
                                  pReq -> CurrentCol  = pReq -> StartCol;
                                  pReq -> CurrentPage = pReq -> EndPage;
                                  pReq -> State = TFT_LCD_STATE_BOT;
                                }
                              }
                              break;
                              
    case TFT_LCD_STATE_BOT  : ColInc = pReq -> EndCol - pReq -> CurrentCol + 1;
                              if (ColInc > 10)
                                ColInc = 10;
                              
                              Mask = TFTLCDBitMask[pReq -> BitShiftB + 1];
                              
                              //����ԭ��������
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Reading();
                              DispData[0] = LCD_Read_Data();    //�����ĵ�һ���ֽ�Ϊ��Ч����,����
                              
                              for (i = 0; i < ColInc; i++)
                                DispData[i] = LCD_Read_Data();
                              
                              //ƴ�Ӳ���д����
                              LCD_Set_Window(pReq -> CurrentCol, pReq -> CurrentPage, pReq -> EndCol, pReq -> EndPage);
                              LCD_Start_Data_Writing();
                              
                              if (pReq -> Type == TFT_LCD_TYPE_INV)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] ^= Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              else if (pReq -> Type == TFT_LCD_TYPE_CLR)
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] &= ~Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              else
                              {
                                for (i = 0; i < ColInc; i++)
                                {
                                  DispData[i] |= Mask;
                                  LCD_Write_Data(DispData[i]);
                                }
                              }
                              
                              pReq -> Offset     += ColInc;
                              pReq -> CurrentCol += ColInc;
                                
                              if (pReq -> CurrentCol > pReq -> EndCol)
                              {
                                pReq -> CurrentCol = pReq -> StartCol;
                                pReq -> CurrentPage++;
                                
                                if (pReq -> CurrentPage > pReq -> EndPage)
                                {
                                  pReq -> State = TFT_LCD_STATE_IDLE;
                                  Rtn = 1;
                                }
                              }
                              break;
                              
    default                 : pReq -> State = TFT_LCD_STATE_IDLE;
                              Rtn = 1;
                              break;
  }

  return Rtn;
}

