📄 guidev.c
字号:
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 + -