569 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			569 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "mywin_inc.h"
 | 
						||
 | 
						||
WIN_LcdStruct *WIN_CreatVirtualLcd(int x_size, int y_size) {
 | 
						||
  WIN_LcdStruct *ret = mymalloc(sizeof(WIN_LcdStruct));
 | 
						||
  mymemset(ret, 0, sizeof(WIN_LcdStruct));
 | 
						||
  ret->x_size = x_size;
 | 
						||
  ret->y_size = y_size;
 | 
						||
  ret->WindowSrcX = 0;
 | 
						||
  ret->WindowSrcY = 0;
 | 
						||
  ret->WindowDstX = ret->x_size - 1;
 | 
						||
  ret->WindowDstY = ret->y_size - 1;
 | 
						||
 | 
						||
  ret->ScreenDis = 1;
 | 
						||
  ret->BackColor = 0;
 | 
						||
  ret->Color = 0xffff;
 | 
						||
  ret->DrawMode = 1;
 | 
						||
 | 
						||
  ret->DrawAddr = mymalloc(ret->x_size * ret->y_size * 2);
 | 
						||
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
void WIN_DeleteVirtualLcd(WIN_LcdStruct *lcd) {
 | 
						||
  if (lcd->DrawAddr)
 | 
						||
    myfree(lcd->DrawAddr);
 | 
						||
  myfree(lcd);
 | 
						||
}
 | 
						||
 | 
						||
// 设置屏幕显示方向
 | 
						||
void WIN_LcdSetScreenDis(WIN_LcdStruct *lcd, int d) {
 | 
						||
  if (d)
 | 
						||
    lcd->ScreenDis = 1;
 | 
						||
  else
 | 
						||
    lcd->ScreenDis = 0;
 | 
						||
}
 | 
						||
 | 
						||
// 设置活动窗口
 | 
						||
void WIN_LcdSetWindow(WIN_LcdStruct *lcd, int x_s, int y_s, int x_size,
 | 
						||
                      int y_size) {
 | 
						||
  int dstx = 0;
 | 
						||
  int dsty = 0;
 | 
						||
  if (x_size < 1)
 | 
						||
    x_size = 1;
 | 
						||
  if (y_size < 1)
 | 
						||
    y_size = 1;
 | 
						||
  if (x_s > lcd->x_size - 1)
 | 
						||
    x_s = lcd->x_size - 1;
 | 
						||
  else if (x_s < 0)
 | 
						||
    x_s = 0;
 | 
						||
  if (y_s > lcd->y_size - 1)
 | 
						||
    y_s = lcd->y_size - 1;
 | 
						||
  else if (y_s < 0)
 | 
						||
    y_s = 0;
 | 
						||
  dstx = x_s + x_size - 1;
 | 
						||
  dsty = y_s + y_size - 1;
 | 
						||
  if (dstx > lcd->x_size - 1)
 | 
						||
    dstx = lcd->x_size - 1;
 | 
						||
  else if (dstx < 0)
 | 
						||
    dstx = 0;
 | 
						||
  if (dsty > lcd->y_size - 1)
 | 
						||
    dsty = lcd->y_size - 1;
 | 
						||
  else if (dsty < 0)
 | 
						||
    dsty = 0;
 | 
						||
  lcd->WindowSrcX = x_s;
 | 
						||
  lcd->WindowSrcY = y_s;
 | 
						||
  lcd->WindowDstX = dstx;
 | 
						||
  lcd->WindowDstY = dsty;
 | 
						||
}
 | 
						||
 | 
						||
int WIN_LcdGetWindowSizeX(WIN_LcdStruct *lcd) {
 | 
						||
  return lcd->WindowDstX - lcd->WindowSrcX + 1;
 | 
						||
}
 | 
						||
 | 
						||
int WIN_LcdGetWindowSizeY(WIN_LcdStruct *lcd) {
 | 
						||
  return lcd->WindowDstY - lcd->WindowSrcY + 1;
 | 
						||
}
 | 
						||
 | 
						||
int WIN_LcdGetLcdSizeX(WIN_LcdStruct *lcd) { return lcd->x_size; }
 | 
						||
 | 
						||
int WIN_LcdGetLcdSizeY(WIN_LcdStruct *lcd) { return lcd->y_size; }
 | 
						||
 | 
						||
u32 WIN_LcdSetLcdColor(WIN_LcdStruct *lcd, u32 color) {
 | 
						||
  u32 ret = lcd->Color;
 | 
						||
  // g_lcd_struct.Color=color;
 | 
						||
  lcd->Color = COLOR888TO565(color);
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdSetLcdBkColor(WIN_LcdStruct *lcd, u32 color) {
 | 
						||
  u32 ret = lcd->BackColor;
 | 
						||
  // g_lcd_struct.BackColor=color;
 | 
						||
  lcd->BackColor = COLOR888TO565(color);
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdSetLcdColor16(WIN_LcdStruct *lcd, u32 color) {
 | 
						||
  u32 ret = lcd->Color;
 | 
						||
  lcd->Color = (color);
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdSetLcdBkColor16(WIN_LcdStruct *lcd, u32 color) {
 | 
						||
  u32 ret = lcd->BackColor;
 | 
						||
  lcd->BackColor = (color);
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdGetLcdColor(WIN_LcdStruct *lcd) {
 | 
						||
  u32 ret = lcd->Color;
 | 
						||
  return COLOR565TO888(ret);
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdGetLcdBkColor(WIN_LcdStruct *lcd) {
 | 
						||
  u32 ret = lcd->BackColor;
 | 
						||
  return COLOR565TO888(ret);
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdGetLcdColor16(WIN_LcdStruct *lcd) {
 | 
						||
  u32 ret = lcd->Color;
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
u32 WIN_LcdGetLcdBkColor16(WIN_LcdStruct *lcd) {
 | 
						||
  u32 ret = lcd->BackColor;
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 设置绘制模式,1,不绘制背景,0,绘制背景
 | 
						||
void WIN_LcdSetLcdDrawMode(WIN_LcdStruct *lcd, int mode) {
 | 
						||
  if (mode) {
 | 
						||
    lcd->DrawMode = 1; // 此时调用画点函数时不绘制背景色
 | 
						||
  } else {
 | 
						||
    lcd->DrawMode = 0;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 填充一条线,以窗口的起点为起点,最大填充到窗口的终点位置
 | 
						||
static void WIN_LcdFillLine16(WIN_LcdStruct *lcd, u16 *buff, int y, int xsize) {
 | 
						||
  u16 *addr = lcd->DrawAddr;
 | 
						||
  int xsizeMax = lcd->WindowDstX + 1 - lcd->WindowSrcX;
 | 
						||
  if (xsize > xsizeMax)
 | 
						||
    xsize = xsizeMax;
 | 
						||
  if (lcd->ScreenDis) {
 | 
						||
    addr = &addr[y * lcd->x_size + lcd->WindowSrcX];
 | 
						||
    for (int x = 0; x < xsize; x++) {
 | 
						||
      addr[x] = *buff;
 | 
						||
      buff++;
 | 
						||
    }
 | 
						||
  } else {
 | 
						||
    addr = &addr[lcd->x_size * lcd->y_size - 1 -
 | 
						||
                 (y * lcd->x_size + lcd->WindowSrcX)];
 | 
						||
    for (int x = 0; x < xsize; x++) {
 | 
						||
      *addr-- = *buff;
 | 
						||
      buff++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 把图像填充到屏幕的活动窗口中,
 | 
						||
// 参数xsize,图像的宽度
 | 
						||
// 参数ysize,图像的高度
 | 
						||
static void WIN_LcdFillRect16(WIN_LcdStruct *lcd, u16 *buff, int xsize,
 | 
						||
                              int ysize) {
 | 
						||
  int ysizeMax = lcd->WindowDstY + 1 - lcd->WindowSrcY;
 | 
						||
  if (ysize > ysizeMax)
 | 
						||
    ysize = ysizeMax;
 | 
						||
  for (int y = 0; y < ysize; y++) {
 | 
						||
    WIN_LcdFillLine16(lcd, buff, y + lcd->WindowSrcY, xsize);
 | 
						||
    buff += xsize;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 把图像偏移之后填充到屏幕的活动窗口中,
 | 
						||
// 参数x_s,图像要显示的横向起始坐标
 | 
						||
// 参数y_s,图像要显示的纵向起始坐标
 | 
						||
// 参数xsize,图像的宽度
 | 
						||
// 参数ysize,图像的高度
 | 
						||
static void WIN_LcdFillRectOff16(WIN_LcdStruct *lcd, u16 *buff, int x_s,
 | 
						||
                                 int y_s, int xsize, int ysize) {
 | 
						||
  int offset = y_s * xsize + x_s;
 | 
						||
  WIN_LcdFillRect16(lcd, buff + offset, xsize, ysize - y_s);
 | 
						||
}
 | 
						||
 | 
						||
// 在活动窗口的指定位置显示图片
 | 
						||
// 参数s_x,图像在绘图窗口中的坐标
 | 
						||
// 参数s_y,图像在绘图冲口中的坐标
 | 
						||
// 参数s_xsize,要绘制的部分图像大小
 | 
						||
// 参数s_ysize,要绘制的部分图像大小
 | 
						||
// 参数x_s,图像要显示的横向起始坐标
 | 
						||
// 参数y_s,图像要显示的纵向起始坐标
 | 
						||
// 参数xsize,图像的宽度
 | 
						||
// 参数ysize,图像的高度
 | 
						||
void WIN_LcdFillRectOff16At(WIN_LcdStruct *lcd, int s_x, int s_y, int s_xsize,
 | 
						||
                            int s_ysize, u16 *buff, int x_s, int y_s, int xsize,
 | 
						||
                            int ysize) {
 | 
						||
  // 保存以前的窗口大小
 | 
						||
  int w_x = lcd->WindowSrcX;
 | 
						||
  int w_y = lcd->WindowSrcY;
 | 
						||
  int w_x_e = lcd->WindowDstX;
 | 
						||
  int w_y_e = lcd->WindowDstY;
 | 
						||
 | 
						||
  // 设置新的窗口大小
 | 
						||
  lcd->WindowSrcX = w_x + s_x;
 | 
						||
  lcd->WindowSrcY = w_y + s_y;
 | 
						||
  lcd->WindowDstX = lcd->WindowSrcX + s_xsize - 1;
 | 
						||
  lcd->WindowDstY = lcd->WindowSrcY + s_ysize - 1;
 | 
						||
  // 限制新的绘图区不能在以前的窗口之外
 | 
						||
  if (lcd->WindowDstX > w_x_e)
 | 
						||
    lcd->WindowDstX = w_x_e;
 | 
						||
  if (lcd->WindowDstY > w_y_e)
 | 
						||
    lcd->WindowDstY = w_y_e;
 | 
						||
 | 
						||
  // 绘图
 | 
						||
  WIN_LcdFillRectOff16(lcd, buff, x_s + s_x, y_s + s_y, xsize, ysize);
 | 
						||
 | 
						||
  // 恢复以前的绘图区
 | 
						||
  lcd->WindowSrcX = w_x;
 | 
						||
  lcd->WindowSrcY = w_y;
 | 
						||
  lcd->WindowDstX = w_x_e;
 | 
						||
  lcd->WindowDstY = w_y_e;
 | 
						||
}
 | 
						||
 | 
						||
// 安全画点,以屏幕窗口的坐标为原点,并且画点不会超出窗口范围
 | 
						||
void WIN_LcdDrawPointSafe(WIN_LcdStruct *lcd, int x, int y, int mode) {
 | 
						||
  x += lcd->WindowSrcX;
 | 
						||
  y += lcd->WindowSrcY;
 | 
						||
  // 在窗口以外的不画
 | 
						||
  if (x < lcd->WindowSrcX || x > lcd->WindowDstX)
 | 
						||
    return;
 | 
						||
  if (y < lcd->WindowSrcY || y > lcd->WindowDstY)
 | 
						||
    return;
 | 
						||
  u16 *DrawAddr = lcd->DrawAddr;
 | 
						||
  if (mode) {
 | 
						||
    if (lcd->ScreenDis)
 | 
						||
      DrawAddr[(y * lcd->x_size + x)] = lcd->Color;
 | 
						||
    else
 | 
						||
      DrawAddr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] =
 | 
						||
          lcd->Color;
 | 
						||
  } else if (lcd->DrawMode == 0) {
 | 
						||
    if (lcd->ScreenDis)
 | 
						||
      DrawAddr[(y * lcd->x_size + x)] = lcd->BackColor;
 | 
						||
    else
 | 
						||
      DrawAddr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] =
 | 
						||
          lcd->BackColor;
 | 
						||
  } else // 当g_lcd_struct.DrawMode==1时不绘制背景色
 | 
						||
  {
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 安全画点,以屏幕窗口的坐标为原点,并且画点不会超出窗口范围
 | 
						||
// 以指定颜色画点,而不是前景色
 | 
						||
void WIN_LcdDrawPointSafeColor(WIN_LcdStruct *lcd, int x, int y, u16 color) {
 | 
						||
  x += lcd->WindowSrcX;
 | 
						||
  y += lcd->WindowSrcY;
 | 
						||
  // 在窗口以外的不画
 | 
						||
  if (x < lcd->WindowSrcX || x > lcd->WindowDstX)
 | 
						||
    return;
 | 
						||
  if (y < lcd->WindowSrcY || y > lcd->WindowDstY)
 | 
						||
    return;
 | 
						||
  u16 *DrawAddr = lcd->DrawAddr;
 | 
						||
  if (1) {
 | 
						||
    if (lcd->ScreenDis)
 | 
						||
      DrawAddr[(y * lcd->x_size + x)] = color;
 | 
						||
    else
 | 
						||
      DrawAddr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] = color;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 快速ALPHA BLENDING算法.
 | 
						||
// src:源颜色
 | 
						||
// dst:目标颜色
 | 
						||
// alpha:透明程度(0~32)
 | 
						||
// 返回值:混合后的颜色.
 | 
						||
static u16 alpha_blend565(u16 src, u16 dst, u8 alpha) {
 | 
						||
  u32 src2;
 | 
						||
  u32 dst2;
 | 
						||
  // Convert to 32bit |-----GGGGGG-----RRRRR------BBBBB|
 | 
						||
  src2 = ((src << 16) | src) & 0x07E0F81F;
 | 
						||
  dst2 = ((dst << 16) | dst) & 0x07E0F81F;
 | 
						||
  // Perform blending R:G:B with alpha in range 0..32
 | 
						||
  // Note that the reason that alpha may not exceed 32 is that there are only
 | 
						||
  // 5bits of space between each R:G:B value, any higher value will overflow
 | 
						||
  // into the next component and deliver ugly result.
 | 
						||
  dst2 = ((((dst2 - src2) * alpha) >> 5) + src2) & 0x07E0F81F;
 | 
						||
  return (dst2 >> 16) | dst2;
 | 
						||
}
 | 
						||
 | 
						||
// 以指定色透明度画点0~32,0,全透明,31,不透明
 | 
						||
void WIN_LcdDrawPointSafeColorAlpha(WIN_LcdStruct *lcd, int x, int y, u16 color,
 | 
						||
                                    u8 alpha) {
 | 
						||
  x += lcd->WindowSrcX;
 | 
						||
  y += lcd->WindowSrcY;
 | 
						||
  // 在窗口以外的不画
 | 
						||
  if (x < lcd->WindowSrcX || x > lcd->WindowDstX)
 | 
						||
    return;
 | 
						||
  if (y < lcd->WindowSrcY || y > lcd->WindowDstY)
 | 
						||
    return;
 | 
						||
  if (alpha > 31)
 | 
						||
    alpha = 31;
 | 
						||
  if (alpha == 0)
 | 
						||
    return;
 | 
						||
  u16 *DrawAddr = lcd->DrawAddr;
 | 
						||
  u16 color_old = 0;
 | 
						||
  if (1) {
 | 
						||
    if (lcd->ScreenDis) {
 | 
						||
      color_old = DrawAddr[(y * lcd->x_size + x)];
 | 
						||
      color = alpha_blend565(color_old, color, alpha);
 | 
						||
      DrawAddr[(y * lcd->x_size + x)] = color;
 | 
						||
    } else {
 | 
						||
      color_old =
 | 
						||
          DrawAddr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)];
 | 
						||
      color = alpha_blend565(color_old, color, alpha);
 | 
						||
      DrawAddr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] = color;
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 填充矩形,已窗口坐标为原点
 | 
						||
void WIN_LcdFillRectByColor(WIN_LcdStruct *lcd, int x, int y, int x_size,
 | 
						||
                            int y_size) {
 | 
						||
  for (int i = y; i < y + y_size; i++) {
 | 
						||
    for (int j = x; j < x + x_size; j++) {
 | 
						||
      WIN_LcdDrawPointSafe(lcd, j, i, 1);
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 以透明度填充矩形,已窗口坐标为原点
 | 
						||
void WIN_LcdFillRectByColorAlpha(WIN_LcdStruct *lcd, int x, int y, int x_size,
 | 
						||
                                 int y_size, u8 alpha) {
 | 
						||
  for (int i = y; i < y + y_size; i++) {
 | 
						||
    for (int j = x; j < x + x_size; j++) {
 | 
						||
      WIN_LcdDrawPointSafeColorAlpha(lcd, j, i, lcd->Color, alpha);
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 绘制图标,图标使用const数组编译在程序里,其本身已经附带了大小等参数
 | 
						||
// 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
 | 
						||
void WIN_LcdDrawImag(WIN_LcdStruct *lcd, int x, int y, int xsize, int ysize,
 | 
						||
                     const u8 *buff) {
 | 
						||
 | 
						||
  if (buff == 0)
 | 
						||
    return;
 | 
						||
 | 
						||
  u8 scan = buff[0];
 | 
						||
  u8 gray = buff[1];
 | 
						||
  u16 w = *((u16 *)&buff[2]);
 | 
						||
  u16 h = *((u16 *)&buff[4]);
 | 
						||
  u8 is565 = buff[6];
 | 
						||
  u8 rgb = buff[7];
 | 
						||
 | 
						||
  // 必须所有参数都符合要求
 | 
						||
  if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
 | 
						||
      (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
 | 
						||
    return;
 | 
						||
 | 
						||
  u16 *imag = (u16 *)(buff + 8);
 | 
						||
 | 
						||
  if (xsize > w)
 | 
						||
    xsize = w;
 | 
						||
  if (ysize > h)
 | 
						||
    ysize = h;
 | 
						||
  for (int j = y; j < y + ysize; j++) {
 | 
						||
    for (int i = 0; i < xsize; i++) {
 | 
						||
      WIN_LcdDrawPointSafe(lcd, i + x, j, imag[i]);
 | 
						||
    }
 | 
						||
    imag += w;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 绘制图标,但是不绘制指定颜色
 | 
						||
void WIN_LcdDrawImagButColor(WIN_LcdStruct *lcd, int x, int y, int xsize,
 | 
						||
                             int ysize, const u8 *buff, u16 color) {
 | 
						||
 | 
						||
  if (buff == 0)
 | 
						||
    return;
 | 
						||
 | 
						||
  u8 scan = buff[0];
 | 
						||
  u8 gray = buff[1];
 | 
						||
  u16 w = *((u16 *)&buff[2]);
 | 
						||
  u16 h = *((u16 *)&buff[4]);
 | 
						||
  u8 is565 = buff[6];
 | 
						||
  u8 rgb = buff[7];
 | 
						||
 | 
						||
  // 必须所有参数都符合要求
 | 
						||
  if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
 | 
						||
      (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
 | 
						||
    return;
 | 
						||
 | 
						||
  u16 *imag = (u16 *)(buff + 8);
 | 
						||
 | 
						||
  if (xsize > w)
 | 
						||
    xsize = w;
 | 
						||
  if (ysize > h)
 | 
						||
    ysize = h;
 | 
						||
  for (int j = y; j < y + ysize; j++) {
 | 
						||
    for (int i = 0; i < xsize; i++) {
 | 
						||
      if (imag[i] != color)
 | 
						||
        WIN_LcdDrawPointSafe(lcd, i + x, j, imag[i]);
 | 
						||
    }
 | 
						||
    imag += w;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 绘制图标,把图像的有效部分绘制为指定颜色
 | 
						||
// 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
 | 
						||
void WIN_LcdDrawImagByColor(WIN_LcdStruct *lcd, int x, int y, int xsize,
 | 
						||
                            int ysize, const u8 *buff, u16 color) {
 | 
						||
 | 
						||
  if (buff == 0)
 | 
						||
    return;
 | 
						||
 | 
						||
  u8 scan = buff[0];
 | 
						||
  u8 gray = buff[1];
 | 
						||
  u16 w = *((u16 *)&buff[2]);
 | 
						||
  u16 h = *((u16 *)&buff[4]);
 | 
						||
  u8 is565 = buff[6];
 | 
						||
  u8 rgb = buff[7];
 | 
						||
 | 
						||
  // 必须所有参数都符合要求
 | 
						||
  if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
 | 
						||
      (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
 | 
						||
    return;
 | 
						||
 | 
						||
  u16 *imag = (u16 *)(buff + 8);
 | 
						||
 | 
						||
  if (xsize > w)
 | 
						||
    xsize = w;
 | 
						||
  if (ysize > h)
 | 
						||
    ysize = h;
 | 
						||
  for (int j = y; j < y + ysize; j++) {
 | 
						||
    for (int i = 0; i < xsize; i++) {
 | 
						||
      if ((imag[i] != 0x0000) && (imag[i] != 0xffff))
 | 
						||
        WIN_LcdDrawPointSafeColor(lcd, i + x, j, color);
 | 
						||
    }
 | 
						||
    imag += w;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 绘制图标,把原图像转化为透明度,用指定颜色来绘制
 | 
						||
// 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数
 | 
						||
void WIN_LcdDrawImagByAlpha(WIN_LcdStruct *lcd, int x, int y, int xsize,
 | 
						||
                            int ysize, const u8 *buff, u16 color) {
 | 
						||
 | 
						||
  if (buff == 0)
 | 
						||
    return;
 | 
						||
 | 
						||
  u8 scan = buff[0];
 | 
						||
  u8 gray = buff[1];
 | 
						||
  u16 w = *((u16 *)&buff[2]);
 | 
						||
  u16 h = *((u16 *)&buff[4]);
 | 
						||
  u8 is565 = buff[6];
 | 
						||
  u8 rgb = buff[7];
 | 
						||
 | 
						||
  // 必须所有参数都符合要求
 | 
						||
  if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
 | 
						||
      (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
 | 
						||
    return;
 | 
						||
 | 
						||
  u16 *imag = (u16 *)(buff + 8);
 | 
						||
  u8 r, g, b;
 | 
						||
  u8 alpha = 0;
 | 
						||
  if (xsize > w)
 | 
						||
    xsize = w;
 | 
						||
  if (ysize > h)
 | 
						||
    ysize = h;
 | 
						||
  for (int j = y; j < y + ysize; j++) {
 | 
						||
    for (int i = 0; i < xsize; i++) {
 | 
						||
      // 只绘制无效窗口内的屏幕
 | 
						||
      //			WIN_Struct *ewin=WIN_GetWinStruct();
 | 
						||
      //			if (POS_InRect
 | 
						||
      //(ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size,i+x,j))
 | 
						||
      {
 | 
						||
        // 白色全透明不绘制,加快速度
 | 
						||
        if ((imag[i] != 0x0000) && (imag[i] != 0xffff)) {
 | 
						||
          WIN_LcdDrawPointSafeColorAlpha(lcd, i + x, j, color,
 | 
						||
                                         31 - (imag[i] >> 11));
 | 
						||
        } else if (imag[i] == 0x0000) {
 | 
						||
          // 不透明直接画原来的颜色
 | 
						||
          WIN_LcdDrawPointSafeColor(lcd, i + x, j, color);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    imag += w;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 清除绘图窗口内的显示
 | 
						||
void WIN_LcdClear(WIN_LcdStruct *lcd) {
 | 
						||
  u16 *addr = lcd->DrawAddr;
 | 
						||
  for (int y = lcd->WindowSrcY; y <= lcd->WindowDstY; y++) {
 | 
						||
    if (lcd->ScreenDis) {
 | 
						||
      for (int x = lcd->WindowSrcX; x <= lcd->WindowDstX; x++) {
 | 
						||
        addr[(y * lcd->x_size + x)] = lcd->BackColor;
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      for (int x = lcd->WindowSrcX; x <= lcd->WindowDstX; x++) {
 | 
						||
        addr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] =
 | 
						||
            lcd->BackColor;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 清除矩形内的显示
 | 
						||
void WIN_LcdClearRect(WIN_LcdStruct *lcd, int x, int y, int x_size,
 | 
						||
                      int y_size) {
 | 
						||
  u16 *addr = lcd->DrawAddr;
 | 
						||
  x = x + lcd->WindowSrcX;
 | 
						||
  y = y + lcd->WindowSrcY;
 | 
						||
  int x_e = x + x_size - 1;
 | 
						||
  if (x_e > lcd->WindowDstX)
 | 
						||
    x_e = lcd->WindowDstX;
 | 
						||
  int y_e = y + y_size - 1;
 | 
						||
  if (y_e > lcd->WindowDstY)
 | 
						||
    y_e = lcd->WindowDstY;
 | 
						||
  int temp = x;
 | 
						||
  for (; y <= y_e; y++) {
 | 
						||
    if (lcd->ScreenDis) {
 | 
						||
      for (x = temp; x <= x_e; x++) {
 | 
						||
        addr[(y * lcd->x_size + x)] = lcd->BackColor;
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      for (x = temp; x <= x_e; x++) {
 | 
						||
        addr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)] =
 | 
						||
            lcd->BackColor;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
// 获取指定矩形空间的屏幕颜色,屏幕的绝对坐标
 | 
						||
void WIN_LcdGetColors(WIN_LcdStruct *lcd, u16 *buff, int x_s, int y_s,
 | 
						||
                      int x_size, int y_size) {
 | 
						||
  u16 *addr = lcd->DrawAddr;
 | 
						||
  if (x_s < 0)
 | 
						||
    x_s = 0;
 | 
						||
  else if (x_s > lcd->x_size - 1)
 | 
						||
    x_s = lcd->x_size - 1;
 | 
						||
  if (y_s < 0)
 | 
						||
    y_s = 0;
 | 
						||
  else if (y_s > lcd->y_size - 1)
 | 
						||
    y_s = lcd->y_size - 1;
 | 
						||
  if (x_size > lcd->x_size - x_s)
 | 
						||
    x_size = lcd->x_size - x_s;
 | 
						||
  else if (x_size < 0)
 | 
						||
    x_size = 0;
 | 
						||
  if (y_size > lcd->y_size - y_s)
 | 
						||
    y_size = lcd->y_size - y_s;
 | 
						||
  else if (y_size < 0)
 | 
						||
    y_size = 0;
 | 
						||
  for (int y = y_s; y < y_size + y_s; y++) {
 | 
						||
    if (lcd->ScreenDis) {
 | 
						||
      for (int x = x_s; x < x_size + x_s; x++) {
 | 
						||
        u32 temp = addr[(y * lcd->x_size + x)];
 | 
						||
        *buff = temp;
 | 
						||
        buff++;
 | 
						||
      }
 | 
						||
    } else {
 | 
						||
      for (int x = x_s; x < x_size + x_s; x++) {
 | 
						||
        u32 temp = addr[lcd->x_size * lcd->y_size - 1 - (y * lcd->x_size + x)];
 | 
						||
        *buff = temp;
 | 
						||
        buff++;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
}
 |