render模块包含三个部分:format,operation和render.c,其中format为图片文件解析模块,operation为操作模块,render.c为渲染函数。
format目录 operation目录 render.c
picfmt_manager.c Zoom.c Merge.c
| |
Bmp.c Jpg.c
format
图片文件解析模块中,picfmt_manager.c管理底层支持的两种图片格式:bmp格式和jpg格式,它们分别向上注册PicFileParser结构体,提供底层的操作函数,并且解析得到的图片信息保存在PixelDatas结构体中。
图片解析模块
typedef struct PicFileParser {
char *name; //图片文件解析模块的名字
/* 是否支持某文件 */
int (*isSupport)(PT_FileMap ptFileMap);
/* 从文件中解析出图像的象素数据 */
int (*GetPixelDatas)(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas);
/* 释放图像的象素数据所占内存 */
int (*FreePixelDatas)(PT_PixelDatas ptPixelDatas);
struct PicFileParser *ptNext; /* 链表 */
}T_PicFileParser, *PT_PicFileParser;
图片的象素数据
typedef struct PixelDatas {
int iWidth; /* 宽度: 一行有多少个象素 */
int iHeight; /* 高度: 一列有多少个象素 */
int iBpp; /* 一个象素用多少位来表示 */
int iLineBytes; /* 一行数据有多少字节 */
int iTotalBytes; /* 所有字节数 */
//象素数据存储的地方,内存首地址
unsigned char *aucPixelDatas;
}T_PixelDatas, *PT_PixelDatas;
picfmt_manager.c通过链表管理底层注册的PicFileParser图片解析模块结构体。
//注册"图片文件解析模块", "图片文件解析模块"就是怎么从BMP/JPG等图片文件中解析出象素数据
int RegisterPicFileParser(PT_PicFileParser ptPicFileParser)
//根据名字取出指定的"图片文件解析模块"
PT_PicFileParser Parser(char *pcName)
//找到能支持指定文件的"图片文件解析模块"
PT_PicFileParser GetParser(PT_FileMap ptFileMap)
operation
图片解析后得到的信息存放在PixelDatas结构体中,以它为参数的函数可以对图片进行放大,合并等操作。
render.c
render.c借助上述函数,可以根据PixelDatas中的图片内容渲染VideoMem内存。其中上部分都是关于图片的渲染,后部分是关于字体的渲染。
//把缓冲区中的数据刷到显示设备上去,即在显示设备上显示缓冲区中的图像
void FlushVideoMemToDev(PT_VideoMem ptVideoMem)
//取出BMP格式的图标文件中的象素数据
int GetPixelDatasForIcon(char *strFileName, PT_PixelDatas ptPixelDatas)
//释放图像数据所占缓冲区
void FreePixelDatasForIcon(PT_PixelDatas ptPixelDatas)
//判断本程序能否支持该图片文件,目前只能支持BMP/JPG格式的文件
int isPictureFileSupported(char *strFileName)
//从图片文件中取出象素数据
int GetPixelDatasFrmFile(char *strFileName, PT_PixelDatas ptPixelDatas)
//GetPixelDatasFrmFile从图片文件中取出象素数据时是动态分配内存的,FreePixelDatasFrmFile把分配的内存释放掉
void FreePixelDatasFrmFile(PT_PixelDatas ptPixelDatas)
//设置VideoMem中某个座标象素的颜色
static int SetColorForPixelInVideoMem(int iX, int iY, PT_VideoMem ptVideoMem, unsigned int dwColor)
//清除VideoMem中某个矩形区域,设为某颜色
void ClearRectangleInVideoMem(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, PT_VideoMem ptVideoMem, unsigned int dwColor)
//是把显示设备上指定区域里每个象素的颜色取反
static void InvertButton(PT_Layout ptLayout)
//要显示的字符是否完全在指定矩形区域内
static int isFontInArea(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, PT_FontBitMap ptFontBitMap)
//根据位图中的数据把字符显示到videomem中
static int MergeOneFontToVideoMem(PT_FontBitMap ptFontBitMap, PT_VideoMem ptVideoMem)
//在VideoMem的指定矩形居中显示字符串
int MergerStringToCenterOfRectangleInVideoMem(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, unsigned char *pucTextString, PT_VideoMem ptVideoMem)
把缓冲区中的数据刷到显示设备上去,即在显示设备上显示缓冲区中的图像,参数为VideoMem结构体。
void FlushVideoMemToDev(PT_VideoMem ptVideoMem){
//如果不是显存,把VideoMem刷到显存上
if (!ptVideoMem->bDevFrameBuffer)
GetDefaultDispDev()->ShowPage(ptVideoMem);
}
取出BMP格式的图标文件中的象素数据,其中需要映射文件,将它当做内存处理。
int GetPixelDatasForIcon(char *strFileName, PT_PixelDatas ptPixelDatas){
T_FileMap tFileMap;
int iXres, iYres, iBpp;
//图标存在 /etc/digitpic/icons 文件名加上路径
snprintf(tFileMap.strFileName, 128, "%s/%s", ICON_PATH, strFileName);
tFileMap.strFileName[127] = '\0';
MapFile(&tFileMap); //映射文件
Parser("bmp")->isSupport(&tFileMap); //是否为bmp格式图片
GetDispResolution(&iXres, &iYres, &iBpp); //获取分辨率
ptPixelDatas->iBpp = iBpp;
Parser("bmp")->GetPixelDatas(&tFileMap, ptPixelDatas); //解析bmp格式的图片文件
UnMapFile(&tFileMap); //取消映射
return 0;
}
void FreePixelDatasForIcon(PT_PixelDatas ptPixelDatas){
Parser("bmp")->FreePixelDatas(ptPixelDatas);
}
判断本程序能否支持该图片文件,目前只能支持BMP/JPG格式的文件
int isPictureFileSupported(char *strFileName){
T_FileMap tFileMap;
int iError;
strncpy(tFileMap.strFileName, strFileName, 256);
tFileMap.strFileName[255] = '\0';
MapFile(&tFileMap); //映射文件
if (GetParser(&tFileMap) == NULL){ //判断能否找到该文件的解析器
UnMapFile(&tFileMap);
return 0;
}
UnMapFile(&tFileMap); //取消映射
return 1;
}
从图片文件中取出象素数据
int GetPixelDatasFrmFile(char *strFileName, PT_PixelDatas ptPixelDatas){
T_FileMap tFileMap;
int iError;
int iXres, iYres, iBpp;
PT_PicFileParser ptParser;
strncpy(tFileMap.strFileName, strFileName, 256);
tFileMap.strFileName[255] = '\0';
MapFile(&tFileMap);
ptParser = GetParser(&tFileMap);
GetDispResolution(&iXres, &iYres, &iBpp);
ptPixelDatas->iBpp = iBpp;
ptParser->GetPixelDatas(&tFileMap, ptPixelDatas);
UnMapFile(&tFileMap);
return 0;
}
void FreePixelDatasFrmFile(PT_PixelDatas ptPixelDatas){
free(ptPixelDatas->aucPixelDatas);
}
设置VideoMem中某个座标象素的颜色
static int SetColorForPixelInVideoMem(int iX, int iY, PT_VideoMem ptVideoMem, unsigned int dwColor){
unsigned char *pucVideoMem;
unsigned short *pwVideoMem16bpp;
unsigned int *pdwVideoMem32bpp;
unsigned short wColor16bpp; /* 565 */
int iRed,iGreen,iBlue;
pucVideoMem = ptVideoMem->tPixelDatas.aucPixelDatas;
pucVideoMem += iY * ptVideoMem->tPixelDatas.iLineBytes + iX * ptVideoMem->tPixelDatas.iBpp / 8;
pwVideoMem16bpp = (unsigned short *)pucVideoMem;
pdwVideoMem32bpp = (unsigned int *)pucVideoMem;
switch (ptVideoMem->tPixelDatas.iBpp){
case 8:{
*pucVideoMem = (unsigned char)dwColor;
return 1;
break;
}
case 16:{
iRed = (dwColor >> (16+3)) & 0x1f;
iGreen = (dwColor >> (8+2)) & 0x3f;
iBlue = (dwColor >> 3) & 0x1f;
wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
*pwVideoMem16bpp = wColor16bpp;
return 2;
break;
}
case 32:{
*pdwVideoMem32bpp = dwColor;
return 4;
break;
}
default :{
return -1;
}
}
return -1;
}
清除VideoMem中某个矩形区域,设为某颜色
void ClearRectangleInVideoMem(int iTopLeftX, int iTopLeftY, int iBotRightX, int iBotRightY, PT_VideoMem ptVideoMem, unsigned int dwColor){
int x, y;
for (y = iTopLeftY; y <= iBotRightY; y++)
for (x = iTopLeftX; x <= iBotRightX; x++)
SetColorForPixelInVideoMem(x, y, ptVideoMem, dwColor);
}
是把显示设备上指定区域里每个象素的颜色取反
static void InvertButton(PT_Layout ptLayout){
int iY;
int i;
int iButtonWidthBytes;
unsigned char *pucVideoMem;
PT_DispOpr ptDispOpr = GetDefaultDispDev();
pucVideoMem = ptDispOpr->pucDispMem; //获取显存
pucVideoMem += ptLayout->iTopLeftY * ptDispOpr->iLineWidth + ptLayout->iTopLeftX * ptDispOpr->iBpp / 8; /* 图标在Framebuffer中的地址 */
iButtonWidthBytes = (ptLayout->iBotRightX - ptLayout->iTopLeftX + 1) * ptDispOpr->iBpp / 8; //图标的行宽
for (iY = ptLayout->iTopLeftY; iY <= ptLayout->iBotRightY; iY++){
for (i = 0; i < iButtonWidthBytes; i++)
pucVideoMem[i] = ~pucVideoMem[i]; /* 取反 */
pucVideoMem += ptDispOpr->iLineWidth;
}
}