1.ShowPage的结构
static void ShowMainPage(PT_PageLayout ptPageLayout)
1. 获得显存
2. 描画数据
3. 刷到设备上去
4. 解放显存
2.代码解析
main_page.h
typedef struct PageLayout {
int iTopLeftX; /* 这个区域的左上角、右下角坐标 */
int iTopLeftY;
int iBotRightX;
int iBotRightY;
int iBpp; /* 一个象素用多少位来表示 */
int iMaxTotalBytes; /* 位图的大小 */
PT_Layout atLayout; /* 数组: 这个区域分成好几个小区域 */
}T_PageLayout, *PT_PageLayout;
mainpage.c
CalcMainPageLayout
/**********************************************************************
* 函数名称: CalcMainPageLayout
* 功能描述: 计算页面中各图标座标值
* 输入参数: 无
* 输出参数: ptPageLayout - 内含各图标的左上角/右下角座标值
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2013/02/08 V1.0 韦东山 创建
***********************************************************************/
static void CalcMainPageLayout(PT_PageLayout ptPageLayout)
{
int iStartY;
int iWidth;
int iHeight;
int iXres, iYres, iBpp;
int iTmpTotalBytes;
PT_Layout atLayout;
atLayout = ptPageLayout->atLayout;
GetDispResolution(&iXres, &iYres, &iBpp);
ptPageLayout->iBpp = iBpp;
/*
* ----------------------
* 1/2 * iHeight
* browse_mode.bmp iHeight
* 1/2 * iHeight
* continue_mod.bmp iHeight
* 1/2 * iHeight
* setting.bmp iHeight
* 1/2 * iHeight
* ----------------------
*/
iHeight = iYres * 2 / 10;
iWidth = iHeight;
iStartY = iHeight / 2;
/* select_fold图标 */
atLayout[0].iTopLeftY = iStartY;
atLayout[0].iBotRightY = atLayout[0].iTopLeftY + iHeight - 1;
atLayout[0].iTopLeftX = (iXres - iWidth * 2) / 2;
atLayout[0].iBotRightX = atLayout[0].iTopLeftX + iWidth * 2 - 1;
iTmpTotalBytes = (atLayout[0].iBotRightX - atLayout[0].iTopLeftX + 1) * (atLayout[0].iBotRightY - atLayout[0].iTopLeftY + 1) * iBpp / 8;
if (ptPageLayout->iMaxTotalBytes < iTmpTotalBytes)
{
ptPageLayout->iMaxTotalBytes = iTmpTotalBytes;
}
/* interval图标 */
atLayout[1].iTopLeftY = atLayout[0].iBotRightY + iHeight / 2 + 1;
atLayout[1].iBotRightY = atLayout[1].iTopLeftY + iHeight - 1;
atLayout[1].iTopLeftX = (iXres - iWidth * 2) / 2;
atLayout[1].iBotRightX = atLayout[1].iTopLeftX + iWidth * 2 - 1;
iTmpTotalBytes = (atLayout[1].iBotRightX - atLayout[1].iTopLeftX + 1) * (atLayout[1].iBotRightY - atLayout[1].iTopLeftY + 1) * iBpp / 8;
if (ptPageLayout->iMaxTotalBytes < iTmpTotalBytes)
{
ptPageLayout->iMaxTotalBytes = iTmpTotalBytes;
}
/* return图标 */
atLayout[2].iTopLeftY = atLayout[1].iBotRightY + iHeight / 2 + 1;
atLayout[2].iBotRightY = atLayout[2].iTopLeftY + iHeight - 1;
atLayout[2].iTopLeftX = (iXres - iWidth * 2) / 2;
atLayout[2].iBotRightX = atLayout[2].iTopLeftX + iWidth * 2 - 1;
iTmpTotalBytes = (atLayout[2].iBotRightX - atLayout[2].iTopLeftX + 1) * (atLayout[2].iBotRightY - atLayout[2].iTopLeftY + 1) * iBpp / 8;
if (ptPageLayout->iMaxTotalBytes < iTmpTotalBytes)
{
ptPageLayout->iMaxTotalBytes = iTmpTotalBytes;
}
}
GeneratePage
/**********************************************************************
* 函数名称: GeneratePage
* 功能描述: 从图标文件中解析出图像数据并放在指定区域,从而生成页面数据
* 输入参数: ptPageLayout - 内含多个图标的文件名和显示区域
* ptVideoMem - 在这个VideoMem里构造页面数据
* 输出参数: 无
* 返 回 值: 0 - 成功
* 其他值 - 失败
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2013/02/08 V1.0 韦东山 创建
***********************************************************************/
int GeneratePage(PT_PageLayout ptPageLayout, PT_VideoMem ptVideoMem)
{
T_PixelDatas tOriginIconPixelDatas;
T_PixelDatas tIconPixelDatas;
int iError;
PT_Layout atLayout = ptPageLayout->atLayout;
/* 描画数据: VideoMem中的页面数据未生成的情况下才执行下面操作 */
if (ptVideoMem->ePicState != PS_GENERATED)
{
ClearVideoMem(ptVideoMem, COLOR_BACKGROUND);
tIconPixelDatas.iBpp = ptPageLayout->iBpp;
/* 分配一个临时的内存, 它用来存放缩放后的图标数据 */
tIconPixelDatas.aucPixelDatas = malloc(ptPageLayout->iMaxTotalBytes);
if (tIconPixelDatas.aucPixelDatas == NULL)
{
return -1;
}
while (atLayout->strIconName)
{
/* 取得图标文件的象素数据 */
iError = GetPixelDatasForIcon(atLayout->strIconName, &tOriginIconPixelDatas);
if (iError)
{
DBG_PRINTF("GetPixelDatasForIcon %s error!\n", atLayout->strIconName);
free(tIconPixelDatas.aucPixelDatas);
return -1;
}
tIconPixelDatas.iHeight = atLayout->iBotRightY - atLayout->iTopLeftY + 1;
tIconPixelDatas.iWidth = atLayout->iBotRightX - atLayout->iTopLeftX+ 1;
tIconPixelDatas.iLineBytes = tIconPixelDatas.iWidth * tIconPixelDatas.iBpp / 8;
tIconPixelDatas.iTotalBytes = tIconPixelDatas.iLineBytes * tIconPixelDatas.iHeight;
/* 把原始的图标象素数据缩放为指定大小 */
PicZoom(&tOriginIconPixelDatas, &tIconPixelDatas);
/* 把缩放后的图标数据,合并到VideoMem的指定区域 */
PicMerge(atLayout->iTopLeftX, atLayout->iTopLeftY, &tIconPixelDatas, &ptVideoMem->tPixelDatas);
/* 释放原始的图标象素数据 */
FreePixelDatasForIcon(&tOriginIconPixelDatas);
atLayout++;
}
/* 数据上面分配的临时内存 */
free(tIconPixelDatas.aucPixelDatas);
ptVideoMem->ePicState = PS_GENERATED;
}
return 0;
}
render.c
/* 图标所在目录 */
#define ICON_PATH "/etc/digitpic/icons"
GetPixelDatasForIcon
/**********************************************************************
* 函数名称: GetPixelDatasForIcon
* 功能描述: 取出BMP格式的图标文件中的象素数据
* 输入参数: strFileName - BMP格式的图标文件名,它位于/etc/digitpic/icons目录下
* 输出参数: ptPixelDatas - 内含象素数据,它所占的空间是通过malloc分配的,
* 不用时需要用FreePixelDatasForIcon来释放
* 返 回 值: 0 - 成功, 其他值 - 失败
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2013/02/08 V1.0 韦东山 创建
***********************************************************************/
int GetPixelDatasForIcon(char *strFileName, PT_PixelDatas ptPixelDatas)
{
T_FileMap tFileMap;
int iError;
int iXres, iYres, iBpp;
/* 图标存在 /etc/digitpic/icons */
/* 函数原型:int snprintf(char* dest_str,size_t size,const char* format,...);
* 将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
* 注意snprintf这类函数使用后需要手动添加'\0'
*/
snprintf(tFileMap.strFileName, 128, "%s/%s", ICON_PATH, strFileName);
tFileMap.strFileName[127] = '\0';
iError = MapFile(&tFileMap);
if (iError)
{
DBG_PRINTF("MapFile %s error!\n", strFileName);
return -1;
}
iError = Parser("bmp")->isSupport(&tFileMap);
if (iError == 0)
{
DBG_PRINTF("can't support this file: %s\n", strFileName);
UnMapFile(&tFileMap);
return -1;
}
GetDispResolution(&iXres, &iYres, &iBpp);
ptPixelDatas->iBpp = iBpp;
iError = Parser("bmp")->GetPixelDatas(&tFileMap, ptPixelDatas);
if (iError)
{
DBG_PRINTF("GetPixelDatas for %s error!\n", strFileName);
UnMapFile(&tFileMap);
return -1;
}
UnMapFile(&tFileMap);
return 0;
}
mainpage.c
ShowMainPage
/**********************************************************************
* 函数名称: ShowMainPage
* 功能描述: 显示"主页面"
* 输入参数: ptPageLayout - 内含多个图标的文件名和显示区域
* 输出参数: 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2013/02/08 V1.0 韦东山 创建
***********************************************************************/
static void ShowMainPage(PT_PageLayout ptPageLayout)
{
PT_VideoMem ptVideoMem;
int iError;
PT_Layout atLayout = ptPageLayout->atLayout;
/* 1. 获得显存 */
ptVideoMem = GetVideoMem(ID("main"), 1);
if (ptVideoMem == NULL)
{
DBG_PRINTF("can't get video mem for main page!\n");
return;
}
/* 2. 描画数据 */
/* 如果还没有计算过各图标的坐标 */
if (atLayout[0].iTopLeftX == 0)
{
CalcMainPageLayout(ptPageLayout);
}
iError = GeneratePage(ptPageLayout, ptVideoMem);
/* 3. 刷到设备上去 */
FlushVideoMemToDev(ptVideoMem);
/* 4. 解放显存 */
PutVideoMem(ptVideoMem);
}