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

猜你喜欢

转载自www.cnblogs.com/huangdengtao/p/12416608.html