#include "mywin_pic.h" #include "string.h" #include "mywin_inc.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 { uint32_t buff_size; // 总大小 uint32_t buff_used; // 使用了多少 // uint32_t buff_tail; //尾部 _pic_data *pic_data; } WIN_PicBuffStruct; static WIN_PicBuffStruct *g_pic_buff; // 创建一个指定大小的字形缓冲区 WIN_PicBuffStruct *WIN_CreatPicBuff(uint32_t 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) { uint32_t *data = (uint32_t *)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; }