⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guidev.c

📁 ucGUI3.90a没有MemDev这是从3.24向上移植的
💻 C
📖 第 1 页 / 共 3 页
字号:
  GUI_MEMDEV * pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);

    return pDev->pfColor2Index(Color);
}

//! 索引到颜色
static LCD_COLOR _Index2Color(int Index)
{
  GUI_MEMDEV * pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);

    return pDev->pfIndex2Color(Index);
}

//! 得到调色反索引掩码
//! @note 3.24版中GUI_MEMDEV无pfGetIndexMask
static int _GetIndexMask(void)
{
  GUI_MEMDEV * pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);

    return pDev->pfGetIndexMask();
}

//! 设置LUT入口
//! @note 加入以兼容3.90a
static void _SetLUTEntry (U8 Pos, LCD_COLOR color) 
{
    GUI_USE_PARA(Pos);
    GUI_USE_PARA(color);
}

//////////////////////////////////////////////////////////////////////////

//! LCD存储设备API函数指针表
//! @note 注意tLCDDEV_APIList结构3.90a与3.24版本不相同!
static const tLCDDEV_APIList _APIList = 
{
    _Color2Index,
    _Index2Color,// added by hiber
    _GetIndexMask,// added by hiber
    _DrawBitmap,
    _DrawHLine,
    _DrawVLine,
    _FillRect,
    _GetPixelIndex,
    _GetRect,
    _SetPixelIndex,
    _XorPixel,
    _SetLUTEntry// added by hiber
};

//////////////////////////////////////////////////////////////////////////

//! 删除一个存储设备
//! @param hMem 存储设备的句柄
void GUI_MEMDEV_Delete(GUI_MEMDEV_Handle hMemDev)
{
    // Make sure memory device is not used
    GUI_LOCK();

    if (hMemDev)
    {
        GUI_MEMDEV *pDev;

        if (GUI_Context.hDevData == hMemDev)
        {
            GUI_SelectLCD();
        }

        pDev = GUI_MEMDEV_H2P(hMemDev);

        /* Delete the associated usage device */
        if (pDev->hUsage)
        {
            GUI_USAGE_DecUseCnt(pDev->hUsage);
        }

        GUI_ALLOC_FREE(hMemDev);
    }

    GUI_UNLOCK();
}

//! 建立一个存储设备(增强版)
//! @param x0 存储设备的X 轴坐标
//! @param y0 存储设备的Y 轴坐标
//! @param XSize 存储设备的X 轴尺寸
//! @param YSize 存储设备的Y 轴尺寸
//! @param Flags 创建标志
GUI_MEMDEV_Handle GUI_MEMDEV_CreateEx(int x0, int y0, int xsize, int ysize, int Flags)
{
    I32 MemSize;
    GUI_USAGE_Handle hUsage = 0;

    #if LCD_BITSPERPIXEL <= 8
        int BytesPerLine = ((8 *xsize + 15) >> 4) << 1; /* Reserve 8 bits for pixels */
    #else
        int BytesPerLine = ((16 *xsize + 15) >> 4) << 1; /* Reserve 16 bits for pixels */
    #endif

    GUI_MEMDEV_Handle hMemDev;

    /* Calc avaliable MemSize */
    MemSize = GUI_ALLOC_GetMaxSize();
    if (!(Flags &GUI_MEMDEV_NOTRANS))
    {
        MemSize = (MemSize / 4) *3; /* We need to reserve some memory for usage object */
    }

    if (ysize <= 0)
    {
        int MaxLines = (MemSize - sizeof(GUI_MEMDEV)) / BytesPerLine;
        ysize = (MaxLines >  - ysize) ?  - ysize: MaxLines;
    }

    if (!(Flags &GUI_MEMDEV_NOTRANS))
    {
        /* Create the usage map */
        hUsage = GUI_USAGE_BM_Create(x0, y0, xsize, ysize, 0);
    }

    /* Check if we can alloc sufficient memory */
    if (ysize <= 0)
    {
        GUI_DEBUG_WARN("GUI_MEMDEV_Create: Too little memory");
        return 0;
    }

    MemSize = ysize * BytesPerLine + sizeof(GUI_MEMDEV);
    hMemDev = GUI_ALLOC_AllocNoInit(MemSize);
    
    // 设置存储设备相关参数
    if (hMemDev)
    {
    GUI_MEMDEV* pDevData = GUI_MEMDEV_H2P(hMemDev);

        pDevData->x0 = x0;
        pDevData->y0 = y0;
        pDevData->XSize = xsize;
        pDevData->YSize = ysize;

        pDevData->NumColors = LCD_GET_NUMCOLORS();
        pDevData->BytesPerLine = BytesPerLine;
        pDevData->hUsage = hUsage;
        pDevData->pfColor2Index = GUI_Context.pDeviceAPI->pfColor2Index;
        pDevData->pfIndex2Color = GUI_Context.pDeviceAPI->pfIndex2Color;
    }
    else
    {
        GUI_DEBUG_WARN("GUI_MEMDEV_Create: Alloc failed");
    }

    return hMemDev;
}

//! 建立一个存储设备
//! @param x0 存储设备的X 轴坐标
//! @param y0 存储设备的Y 轴坐标
//! @param XSize 存储设备的X 轴尺寸
//! @param YSize 存储设备的Y 轴尺寸
//! @return 建立的存储设备的句柄,如果函数执行失败,返回值为0。
GUI_MEMDEV_Handle GUI_MEMDEV_Create(int x0, int y0, int xsize, int ysize)
{
    return GUI_MEMDEV_CreateEx(x0, y0, xsize, ysize, GUI_MEMDEV_HASTRANS);
}

//! 激活一个存储设备(或如果句柄为0 则激活LCD)
//! @param hMem 存储设备的句柄
//! @note 修改返回类型为GUI_MEMDEV_Handle(原为void),以适应3.90a
GUI_MEMDEV_Handle GUI_MEMDEV_Select(GUI_MEMDEV_Handle hMem)
{

    GUI_MEMDEV_Handle hMemOld = GUI_Context.hDevData;

    if (hMem == 0)
    {
        GUI_SelectLCD();
    }
    else
    {
        #if GUI_WINSUPPORT
            WM_Deactivate();
        #endif

        // If LCD was selected Save cliprect
        if (GUI_Context.hDevData == 0)
        {
            GUI_Context.ClipRectPrev = GUI_Context.ClipRect;
        }

        GUI_Context.hDevData = hMem;// 用于存储设备的内存块内柄
        GUI_Context.pDeviceAPI = &_APIList;// 绘图函数使用存储设备的API

        LCD_SetClipRectMax();// 当前绘图剪辑区为整个LCD屏幕
    }

    return hMemOld;// 返回原来的用于存储设备的内存块内柄
}

#if LCD_BITSPERPIXEL <=8
    #define BITSPERPIXEL 8//!< 若LCD每像素不超过8位,定义存储设备的每点像素为8位
#else
    #define BITSPERPIXEL 16//!< 若LCD每像素超过8位,定义存储设备的每点像素为16位
#endif
#define BYTESPERLINE (BITSPERPIXEL/8)//!< 每行的字节数?

//! 将一个存储设备的内容从内存拷贝到LCD指定坐标。
//! @param hMem 存储设备的句柄
//! @param x LCD的x坐标
//! @param y LCD的y坐标
//! @note 只绘制已更改的数据
static void _CopyToLCDAt(GUI_MEMDEV_Handle hMem, int x, int y)
{
    /* Make sure the memory handle is valid */
    if (!hMem)
    {
        return ;
    }

    // 大括号
    {
        GUI_MEMDEV *pDev = GUI_MEMDEV_H2P(hMem);
        GUI_USAGE_h hUsage = pDev->hUsage;
        GUI_USAGE *pUsage;
        int YSize = pDev->YSize;
        int yi;
        int BytesPerLine = pDev->BytesPerLine;
        U8 *pData = (U8*)(pDev + 1);

        if (hUsage)
        {
            pUsage = GUI_USAGE_H2P(hUsage);
            for (yi = 0; yi < YSize; yi++)
            {
                int xOff = 0;
                int XSize;
                XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);

                if (XSize == pDev->XSize)
                {
                    /* If the entire line is affected, calculate the number of entire lines */
                    int y0 = yi;
                    while ((GUI_USAGE_GetNextDirty(pUsage, &xOff, yi + 1)) == XSize)
                    {
                        yi++;
                    }

                    LCD_DrawBitmap(x, y + y0, pDev->XSize, yi - y0 + 1, 1, 1,
                                        BITSPERPIXEL, BytesPerLine, pData, NULL);
                    pData += (yi - y0 + 1) *BytesPerLine;
                }
                else
                {
                    /* Draw the partial line which needs to be drawn */
                    for (; XSize;)
                    {
                        LCD_DrawBitmap(x + xOff, y + yi, XSize, 1, 1, 1, BITSPERPIXEL, 
                                        BytesPerLine, pData + xOff * BYTESPERLINE, NULL);
                        xOff += XSize;
                        XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);
                    }

                    pData += BytesPerLine;
                }
            }
        }
        else
        {
            LCD_DrawBitmap(x, y, pDev->XSize, YSize, 1, 1, BITSPERPIXEL, BytesPerLine, pData, NULL);
        }
    }

    GUI_ALLOC_UNLOCK(hMem);
}

#if (GUI_WINSUPPORT)

#define WM_LOCK() GUI_LOCK()
#define WM_UNLOCK() GUI_UNLOCK() 

//! 将一个存储设备的内容从内存拷贝到LCD指定坐标。
//! @param hMem 存储设备的句柄
//! @param x LCD的x坐标
//! @param y LCD的y坐标
void GUI_MEMDEV_CopyToLCDAt(GUI_MEMDEV_Handle hMem, int x, int y)
{
    if (hMem)
    {
        WM_LOCK();
        {
            GUI_MEMDEV_Handle hMemPrev = GUI_Context.hDevData;
            GUI_MEMDEV *pDevData = (GUI_MEMDEV*)GUI_ALLOC_LOCK(hMem); /* Convert to pointer */
            GUI_RECT r;

            /* Make sure LCD is selected as device */
            if (hMemPrev)
            {
                GUI_MEMDEV_Select(0); /* Activate LCD */
            }

            if (x == POS_AUTO)
            {
                x = pDevData->x0;
                y = pDevData->y0;
            }

            /* Calculate rectangle */
            r.x1 = (r.x0 = x) + pDevData->XSize - 1;
            r.y1 = (r.y0 = y) + pDevData->YSize - 1;

            /* Do the drawing. WIndow manager has to be on */
            WM_Activate();
            WM_ITERATE_START(&r)
            {
                _CopyToLCDAt(hMem, x, y);
            }

            WM_ITERATE_END();
            /* Reactivate previously used device */
            GUI_MEMDEV_Select(hMemPrev);
        }

        WM_UNLOCK();
    }
}
#else
//! 将一个存储设备的内容从内存拷贝到LCD指定坐标。
//! @param hMem 存储设备的句柄
//! @param x LCD的x坐标
//! @param y LCD的y坐标
void GUI_MEMDEV_CopyToLCDAt(GUI_MEMDEV_Handle hMem, int x, int y)
{
    GUI_MEMDEV_Handle hMemPrev = GUI_Context.hDevData;
    GUI_MEMDEV *pDevData = (GUI_MEMDEV*)GUI_ALLOC_LOCK(hMem); /* Convert to pointer */

    /* Make sure LCD is selected as device */
    if (hMemPrev)
    {
        GUI_MEMDEV_Select(0); /* Activate LCD */
    }

    if (x == POS_AUTO)
    {
        x = pDevData->x0;
        y = pDevData->y0;
    }

    _CopyToLCDAt(hMem, x, y);
    /* Reactivate previously used memory device */
    if (hMemPrev)
    {
        GUI_MEMDEV_Select(hMemPrev);
    }
}
#endif

//! 将一个存储设备的内容从内存拷贝到LCD。
//! @param hMem 存储设备的句柄
void GUI_MEMDEV_CopyToLCD(GUI_MEMDEV_Handle hMem) 
{
    GUI_MEMDEV_CopyToLCDAt(hMem, POS_AUTO, POS_AUTO);
}

#else

void GUIDEV(void) 
{
    // do nothing...
}

#endif /* GUI_SUPPORT_MEMDEV && (LCD_BITSPERPIXEL <= 8) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -