📄 guidev.c
字号:
static void _DrawBitmap (int x0, int y0,
int xsize, int ysize,
int BitsPerPixel,
int BytesPerLine,
const U8* pData, int Diff,
const LCD_PIXELINDEX* pTrans)
{
int i;
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
GUI_USAGE* pUsage = (pDev->hUsage) ? GUI_USAGE_h2p(pDev->hUsage) : 0;
/* Mark all affected pixels dirty unless transparency is set */
if (pUsage) {
if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) ==0) {
for (i=0; i<ysize; i++) {
GUI_USAGE_AddHLine(pUsage, x0+Diff,y0+i,xsize);
}
}
}
/* Handle 8 bpp bitmaps seperately as we have different routine bitmaps with or without palette */
x0+=Diff;
/* handle 16 bpp bitmaps in high color modes, but only without palette */
#if LCD_BITSPERPIXEL >8
if (BitsPerPixel==16) {
for (i=0; i<ysize; i++) {
DrawBitLine16BPP_DDB(pUsage, x0, i+y0, (U16*)pData, xsize);
pData += BytesPerLine;
}
return;
}
#endif
/* handle 8 bpp bitmaps */
if (BitsPerPixel==8) {
for (i=0; i<ysize; i++) {
if (pTrans) {
DrawBitLine8BPP(pUsage, x0, i+y0, pData, xsize, pTrans);
} else {
DrawBitLine8BPP_DDB(pUsage, x0, i+y0, pData, xsize);
}
pData += BytesPerLine;
}
return;
}
/* Use aID for bitmaps without palette */
if (!pTrans) {
pTrans = aID;
}
for (i=0; i<ysize; i++) {
switch (BitsPerPixel) {
case 1:
DrawBitLine1BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
break;
case 2:
DrawBitLine2BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
break;
case 4:
DrawBitLine4BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
break;
}
pData += BytesPerLine;
}
}
static void _DrawHLine (int x0, int y, int x1) {
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
GUI_USAGE_h hUsage = pDev->hUsage;
if (hUsage)
GUI_USAGE_AddHLine(GUI_USAGE_h2p(hUsage), x0,y,x1-x0+1);
{
int len = x1-x0+1;
LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x0,y);
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
int NumColorsM1 = pDev->NumColors-1;
do {
*pData = NumColorsM1 - *pData;
pData++;
} while (--len);
} else { /* Fill */
#if LCD_BITSPERPIXEL <=8
memset (pData, LCD_COLORINDEX, len);
#else
*pData = LCD_COLORINDEX; /* We write at least one pixel, so this is permitted ...
(speed optimization) */
while (--len) {
*++pData = LCD_COLORINDEX;
}
#endif
}
}
}
static void _DrawVLine (int x , int y0, int y1) {
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
GUI_USAGE_h hUsage = pDev->hUsage;
GUI_USAGE* pUsage = hUsage ? GUI_USAGE_h2p(hUsage) : NULL;
int NumColorsM1 = pDev->NumColors-1;
LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y0);
do {
if (hUsage)
GUI_USAGE_AddPixel(pUsage, x,y0);
if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR)
*pData = NumColorsM1 - *pData;
else
*pData = LCD_COLORINDEX;
#if LCD_BITSPERPIXEL <= 8
pData += pDev->BytesPerLine;
#else
pData += pDev->BytesPerLine>>1;
#endif
} while (++y0<=y1);
}
static void _SetPixelIndex (int x, int y, int Index){
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
GUI_USAGE_h hUsage = pDev->hUsage;
LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
*pData = Index;
if (hUsage) {
GUI_USAGE* pUsage = GUI_USAGE_h2p(hUsage);
GUI_USAGE_AddPixel(pUsage, x,y);
}
}
static void _XorPixel (int x, int y) {
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
GUI_USAGE_h hUsage = pDev->hUsage;
LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
*pData = pDev->NumColors - 1-*pData;
if (hUsage) {
GUI_USAGE* pUsage = GUI_USAGE_h2p(hUsage);
GUI_USAGE_AddPixel(pUsage, x,y);
}
}
static unsigned int _GetPixelIndex (int x, int y){
LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
return *pData;
}
static void _FillRect (int x0, int y0, int x1, int y1){
for (; y0 <= y1; y0++) {
_DrawHLine(x0,y0, x1);
}
}
static void _GetRect (GUI_RECT* pRect) {
GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
pRect->x0 = pDev->x0;
pRect->y0 = pDev->y0;
pRect->x1 = pDev->x0 + pDev->XSize-1;
pRect->y1 = pDev->y0 + pDev->YSize-1;
}
static unsigned int _Color2Index (LCD_COLOR Color) {
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);
}
/*********************************************************************
*
* Device structure
*
**********************************************************************
*/
static const tLCDDEV_APIList _APIList = {
_Color2Index,
_DrawBitmap,
_DrawHLine,
_DrawVLine,
_FillRect,
_GetPixelIndex,
_GetRect,
_Index2Color,
_SetPixelIndex,
_XorPixel
};
/*
*********************************************************
*
* Exported routines
*
*********************************************************
*/
/*
*************************************************
* *
* Delete *
* *
*************************************************
*/
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();
}
/************************************************
*
* CreateEx
*
*************************************************
*/
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_ALLOC(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;
}
/************************************************
*
* Create
*
*************************************************
*/
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);
}
/************************************************
*
* Select
*
*************************************************
*/
void GUI_MEMDEV_Select(GUI_MEMDEV_Handle hMem) {
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;
LCD_SetClipRectMax();
}
}
/*
*************************************************
* *
* CopyToLCDAt *
* *
*************************************************
*/
#if LCD_BITSPERPIXEL <=8
#define BITSPERPIXEL 8
#else
#define BITSPERPIXEL 16
#endif
#define BYTESPERLINE (BITSPERPIXEL/8)
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)
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
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
/*
*************************************************
* *
* CopyToLCD *
* *
*************************************************
*/
void GUI_MEMDEV_CopyToLCD(GUI_MEMDEV_Handle hMem) {
GUI_MEMDEV_CopyToLCDAt(hMem, POS_AUTO, POS_AUTO);
}
#else
void GUIDEV(void) {}
#endif /* GUI_SUPPORT_MEMDEV && (LCD_BITSPERPIXEL <= 8) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -