8.4.2 MainPage的页面管理

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);
}

posted @ 2020-03-06 15:35  人民广场的二道贩子  阅读(450)  评论(0)    收藏  举报