233 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "mywin_pic.h"
 | 
						||
#include "string.h"
 | 
						||
 | 
						||
// 定义图片缓冲区名称最大大小
 | 
						||
#define WIN_PICBUFF_NAME_MAXLEN 100
 | 
						||
 | 
						||
// 定义图片缓冲池的个数
 | 
						||
#define PICBUFF_NUM 30
 | 
						||
 | 
						||
typedef struct {
 | 
						||
  WIN_PicStruct pic;
 | 
						||
  char name[WIN_PICBUFF_NAME_MAXLEN];
 | 
						||
} _pic_data;
 | 
						||
 | 
						||
typedef struct {
 | 
						||
  u32 buff_size; // 总大小
 | 
						||
  u32 buff_used; // 使用了多少
 | 
						||
  //	u32 buff_tail;			//尾部
 | 
						||
  _pic_data *pic_data;
 | 
						||
} WIN_PicBuffStruct;
 | 
						||
 | 
						||
static WIN_PicBuffStruct *g_pic_buff;
 | 
						||
 | 
						||
// 创建一个指定大小的字形缓冲区
 | 
						||
WIN_PicBuffStruct *WIN_CreatPicBuff(u32 size) {
 | 
						||
  WIN_PicBuffStruct *ret = mycalloc(sizeof(WIN_PicBuffStruct));
 | 
						||
  if (ret == 0)
 | 
						||
    return ret;
 | 
						||
 | 
						||
  ret->pic_data = mymalloc_exm(sizeof(_pic_data) * size);
 | 
						||
  if (ret->pic_data == 0) {
 | 
						||
    myfree(ret);
 | 
						||
    ret = 0;
 | 
						||
    return ret;
 | 
						||
  }
 | 
						||
  mymemset(ret->pic_data, 0, sizeof(_pic_data) * size);
 | 
						||
  ret->buff_size = size;
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 删除一个图片缓冲区
 | 
						||
void WIN_DeletePicBuff(WIN_PicBuffStruct *pb) {
 | 
						||
  if (pb) {
 | 
						||
    for (int i = 0; i < pb->buff_used; i++) {
 | 
						||
      _pic_data *pic_data = &pb->pic_data[i];
 | 
						||
      if (pic_data->pic.data)
 | 
						||
        myfree(pic_data->pic.data);
 | 
						||
    }
 | 
						||
    myfree(pb->pic_data);
 | 
						||
    myfree(pb);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
_pic_data *WIN_PicUsed(WIN_PicBuffStruct *pb, int index) {
 | 
						||
  _pic_data *pic_data = 0;
 | 
						||
  pic_data = &pb->pic_data[index];
 | 
						||
  if (index != 0) {
 | 
						||
    _pic_data *pic_temp = mymalloc(sizeof(_pic_data));
 | 
						||
    _pic_data *pic_first = &pb->pic_data[index - 1];
 | 
						||
    mymemcpy(pic_temp, pic_data, sizeof(_pic_data));
 | 
						||
    mymemcpy(pic_data, pic_first, sizeof(_pic_data));
 | 
						||
    mymemcpy(pic_first, pic_temp, sizeof(_pic_data));
 | 
						||
    myfree(pic_temp);
 | 
						||
    pic_data = pic_first;
 | 
						||
  }
 | 
						||
  return pic_data;
 | 
						||
}
 | 
						||
 | 
						||
// 搜索缓冲区中的图片数据
 | 
						||
WIN_PicStruct *WIN_SearchPicData(WIN_PicBuffStruct *pb, const char *name) {
 | 
						||
  WIN_PicStruct *ret = 0;
 | 
						||
  if (pb) {
 | 
						||
    for (int i = 0; i < pb->buff_used; i++) {
 | 
						||
      int index = i;
 | 
						||
      _pic_data *pic_data = 0;
 | 
						||
      pic_data = &pb->pic_data[index];
 | 
						||
      if (strcmp(pic_data->name, name) == 0) {
 | 
						||
        // 使用了一次,排名向前
 | 
						||
        pic_data = WIN_PicUsed(pb, index);
 | 
						||
 | 
						||
        ret = &pic_data->pic;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 在index的位置留出插入新字符的空间
 | 
						||
int WIN_InsertPic(WIN_PicBuffStruct *pb, _pic_data *data, int index) {
 | 
						||
  if (pb == 0)
 | 
						||
    return 0;
 | 
						||
  if (index > pb->buff_used)
 | 
						||
    return 0;
 | 
						||
  int num = pb->buff_used - index;
 | 
						||
  _pic_data *pic_data = &pb->pic_data[index];
 | 
						||
 | 
						||
  // index之后的向后移
 | 
						||
  if (pb->buff_used >= pb->buff_size) {
 | 
						||
    // 缓冲池已满,删除最后一个
 | 
						||
    _pic_data *end = &pb->pic_data[pb->buff_used - 1];
 | 
						||
    myfree(end->pic.data);
 | 
						||
    printf("%s:del pic,%s\r\n", __func__, end->name);
 | 
						||
    mymemset(end->name, 0, WIN_PICBUFF_NAME_MAXLEN);
 | 
						||
  } else {
 | 
						||
    pb->buff_used++;
 | 
						||
  }
 | 
						||
  // 直接向后移
 | 
						||
  for (int i = num; i > 0; i--) {
 | 
						||
    _pic_data *end = &pic_data[i];
 | 
						||
    _pic_data *first = &pic_data[i - 1];
 | 
						||
    mymemcpy(end, first, sizeof(_pic_data));
 | 
						||
  }
 | 
						||
  // 插入新的字符
 | 
						||
  mymemcpy(pic_data, data, sizeof(_pic_data));
 | 
						||
  printf("%s:add pic,%s\r\n", __func__, pic_data->name);
 | 
						||
  return 1;
 | 
						||
}
 | 
						||
 | 
						||
// 添加图片数据
 | 
						||
int WIN_AddPicData(WIN_PicBuffStruct *pb, WIN_PicStruct *pic,
 | 
						||
                   const char *name) {
 | 
						||
  if (pb) {
 | 
						||
    _pic_data *pic_data = mymalloc(sizeof(_pic_data));
 | 
						||
    int len = strlen(name);
 | 
						||
    if (len + 1 > WIN_PICBUFF_NAME_MAXLEN) {
 | 
						||
      printf("%s:err,pic name to long\r\n", __func__);
 | 
						||
    }
 | 
						||
    mymemcpy(pic_data->name, (void *)name, len + 1);
 | 
						||
    mymemcpy(&pic_data->pic, pic, sizeof(WIN_PicStruct));
 | 
						||
    if (WIN_InsertPic(pb, pic_data, pb->buff_used / 2) == 0)
 | 
						||
      printf("%s:insert pic err \r\n", __func__);
 | 
						||
    myfree(pic_data);
 | 
						||
  }
 | 
						||
  return 0;
 | 
						||
}
 | 
						||
 | 
						||
// 根据名称获取图片
 | 
						||
WIN_PicStruct *WIN_GetPic(const char *name) {
 | 
						||
  if (name == 0)
 | 
						||
    return 0;
 | 
						||
  WIN_PicStruct *ret = 0;
 | 
						||
  if (g_pic_buff == 0)
 | 
						||
    g_pic_buff = WIN_CreatPicBuff(PICBUFF_NUM);
 | 
						||
  ret = WIN_SearchPicData(g_pic_buff, name);
 | 
						||
  if (ret == 0) {
 | 
						||
    WIN_PicStruct pic = {0};
 | 
						||
    if (WIN_DecodeImg(&pic, name) == 0) {
 | 
						||
      WIN_AddPicData(g_pic_buff, &pic, name);
 | 
						||
    }
 | 
						||
    ret = WIN_SearchPicData(g_pic_buff, name);
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 根据名称获取图片,去除图片的透明度信息
 | 
						||
WIN_PicStruct *WIN_GetPicNoAlpha(const char *name) {
 | 
						||
  WIN_PicStruct *ret = 0;
 | 
						||
  if (g_pic_buff == 0)
 | 
						||
    g_pic_buff = WIN_CreatPicBuff(PICBUFF_NUM);
 | 
						||
  ret = WIN_SearchPicData(g_pic_buff, name);
 | 
						||
  if (ret == 0) {
 | 
						||
    WIN_PicStruct pic = {0};
 | 
						||
    if (WIN_DecodeImg(&pic, name) == 0) {
 | 
						||
      if (pic.format == PIC_FORMAT_ARGB8888) {
 | 
						||
        u32 *data = (u32 *)pic.data;
 | 
						||
        pic.data = mymalloc_exm(pic.xsize * pic.ysize * 2);
 | 
						||
        for (int i = 0; i < pic.xsize * pic.ysize; i++)
 | 
						||
          pic.data[i] = COLOR888TO565(data[i]);
 | 
						||
        pic.format = PIC_FORMAT_RGB565;
 | 
						||
        myfree(data);
 | 
						||
      }
 | 
						||
      WIN_AddPicData(g_pic_buff, &pic, name);
 | 
						||
    }
 | 
						||
    ret = WIN_SearchPicData(g_pic_buff, name);
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 判断pic是否在另一个pic内
 | 
						||
int WIN_PicInsidePic(WIN_PicStruct *base, WIN_PicStruct *child) {
 | 
						||
  int ret = 0;
 | 
						||
  if (base && child && base->data && child->data && base->xsize &&
 | 
						||
      base->ysize && child->xsize && child->ysize) {
 | 
						||
    if (base->format == child->format) {
 | 
						||
      int base_size = base->xsize * base->ysize;
 | 
						||
      int child_size = child->xsize * child->ysize;
 | 
						||
      if (base->format == PIC_FORMAT_ARGB8888) {
 | 
						||
        base_size *= 2;
 | 
						||
        child_size *= 2;
 | 
						||
      }
 | 
						||
      if ((child->data >= base->data) &&
 | 
						||
          (child->data + child_size <= base->data + base_size)) {
 | 
						||
        ret = 1;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 图像是否存在
 | 
						||
int WIN_GetPicLive(WIN_PicStruct *pic) {
 | 
						||
  int ret = 0;
 | 
						||
  WIN_PicBuffStruct *pb = g_pic_buff;
 | 
						||
  if (pb && pic && pic->data) {
 | 
						||
    for (int i = 0; i < pb->buff_used; i++) {
 | 
						||
      int index = i;
 | 
						||
      _pic_data *pic_data = 0;
 | 
						||
      pic_data = &pb->pic_data[index];
 | 
						||
      if (WIN_PicInsidePic(&pic_data->pic, pic)) {
 | 
						||
 | 
						||
        ret = 1;
 | 
						||
        break;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return ret;
 | 
						||
}
 | 
						||
 | 
						||
// 安全地绘制pic,返回0,没有pic图像
 | 
						||
int WIN_DrawPic(WIN_PicStruct *pic, int x, int y, int xsize, int ysize) {
 | 
						||
  if (pic && WIN_GetPicLive(pic)) {
 | 
						||
    if (pic->format == PIC_FORMAT_ARGB8888) {
 | 
						||
      WIN_FillRectAlpha(x, y, xsize, ysize, pic->data, 0, 0, pic->xsize,
 | 
						||
                        pic->ysize);
 | 
						||
    } else {
 | 
						||
      WIN_FillRect(x, y, xsize, ysize, pic->data, 0, 0, pic->xsize, pic->ysize);
 | 
						||
    }
 | 
						||
    return 1;
 | 
						||
  }
 | 
						||
  return 0;
 | 
						||
}
 |