www.pudn.com > uCGUI3.24-MemDev-for-3.90a.rar > GUIDEV.c
/*! @file GUIDEV.c * Implementation of memory devices * * @author hiber modified * @author Copyleft (C) 1981-2006, All Rights Givenup * @date 04/18/2006 * @version * * @note * @attention * @warning * @bug * * @todo * @example* @see */ #include #include "GUI_Private.h" #include "GUIDebug.h" ////////////////////////////////////////////////////////////////////////// // HIBER #if GUI_WINSUPPORT //#include "wm.h" #endif #if GUI_SUPPORT_MEMDEV #define GUI_ALLOC_H2P(h) _GUI_ALLOC_h2p_Lock(h) #define GUI_ALLOC_FREE(handle) GUI_ALLOC_Free(handle) #define GUI_ALLOC_LOCK(handle) _GUI_ALLOC_h2p_Lock(handle) #define GUI_ALLOC_UNLOCK(handle) #ifdef GUI_USAGE_H2P #undef GUI_USAGE_H2P #define GUI_USAGE_H2P(h) ((GUI_USAGE*)_GUI_ALLOC_h2p_Lock(h)) #endif #ifdef GUI_MEMDEV_H2P #undef GUI_MEMDEV_H2P #define GUI_MEMDEV_H2P _GUI_ALLOC_h2p_Lock #endif const struct tLCDDEV_APIList_struct GUI_MEMDEV__APIList8 = {NULL};// 兼容3.90a //! 适应3.90a版,带LOCK的GUI_ALLOC_h2p void* _GUI_ALLOC_h2p_Lock(GUI_HMEM hMem) { void * p; GUI_LOCK(); p = GUI_ALLOC_h2p(hMem); GUI_UNLOCK(); return p; } ////////////////////////////////////////////////////////////////////////// #define POS_AUTO -4095 /* Position value for auto-pos */ //! This table contains 0, 1, 2, ... and serves as translation table for DDBs #define INTS(Base) Base+0,Base+1,Base+2,Base+3,Base+4,Base+5, \ Base+6,Base+7,Base+8,Base+9,Base+10,Base+11, \ Base+12,Base+13,Base+14,Base+15 //! 颜色转换表结构(用于DDB-设备相关位图) static const LCD_PIXELINDEX aID[] = { INTS(0) }; ////////////////////////////////////////////////////////////////////////// //! internal routines (not part of interface table) //! @note 原函数名为GUI_MEMDEV_XY2PTR,修改已适应3.90a void *GUI_MEMDEV__XY2PTR(int x, int y) { GUI_MEMDEV* pDev = GUI_ALLOC_H2P(GUI_Context.hDevData); U8 *pData = (U8*)(pDev+1); ////////////////////////////////////////////////////////////////////////// #if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL if ((x >= pDev->x0 + pDev->XSize) | (x < pDev->x0) | (y >= pDev->y0 + pDev->YSize) | (y < pDev->y0)) { GUI_DEBUG_ERROROUT2("GUI_MEMDEV_XY2PTR: parameters out of bounds", x, y); } #endif pData += (y - pDev->y0) *pDev->BytesPerLine; return ((LCD_PIXELINDEX*)pData) + x - pDev->x0; } //! 存储设备绘制1位直线 static void DrawBitLine1BPP(GUI_USAGE *pUsage, int x, int y, U8 const *p, int Diff, int xsize, const LCD_PIXELINDEX *pTrans) { LCD_PIXELINDEX pixels; LCD_PIXELINDEX Index0 = *(pTrans + 0); LCD_PIXELINDEX Index1 = *(pTrans + 1); LCD_PIXELINDEX *pData; U8 PixelCnt; GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData); PixelCnt = 8-(Diff &7); pixels = (*p) << (Diff &7); pData = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); GUI_DEBUG_ERROROUT3_IF(x < pDev->x0, "GUIDEV.c: DrawBitLine1BPP, Act= %d, Border= %d, Clip= %d", x, pDev->x0, GUI_Context.ClipRect.x0); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: /* Write mode */ PixelLoopWrite: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { *pData++ = (pixels &0x80) ? Index1 : Index0; pixels <<= 1; } while (--PixelCnt); if (xsize) { PixelCnt = 8; pixels = *(++p); goto PixelLoopWrite; } break; case LCD_DRAWMODE_TRANS: PixelLoopTrans: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { if ((pixels &0x80)) { if (pUsage) { GUI_USAGE_AddPixel(pUsage, x, y); } *pData = Index1; } x++; pData++; pixels <<= 1; } while (--PixelCnt); if (xsize) { PixelCnt = 8; pixels = *(++p); goto PixelLoopTrans; } break; case LCD_DRAWMODE_XOR: ; PixelLoopXor: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { if ((pixels &0x80)) { *pData = pDev->NumColors - 1- *pData; } pData++; pixels <<= 1; } while (--PixelCnt); if (xsize) { PixelCnt = 8; pixels = *(++p); goto PixelLoopXor; } break; } } //! 存储设备绘制2位直线 static void DrawBitLine2BPP(GUI_USAGE *pUsage, int x, int y, U8 const *p, int Diff, int xsize, const LCD_PIXELINDEX *pTrans) { U8 pixels; U8 PixelCnt; LCD_PIXELINDEX *pData; PixelCnt = 4-(Diff &3); pixels = (*p) << ((Diff &3) << 1); pData = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: /* Write mode */ PixelLoopWrite: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { *pData++ = *(pTrans + (pixels >> 6)); pixels <<= 2; } while (--PixelCnt); if (xsize) { PixelCnt = 4; pixels = *(++p); goto PixelLoopWrite; } break; case LCD_DRAWMODE_TRANS: PixelLoopTrans: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { if (pixels &0xc0) { *pData = *(pTrans + (pixels >> 6)); GUI_USAGE_AddPixel(pUsage, x, y); } pData++; pixels <<= 2; } while (--PixelCnt); if (xsize) { PixelCnt = 4; pixels = *(++p); goto PixelLoopTrans; } break; case LCD_DRAWMODE_XOR: PixelLoopXor: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { if ((pixels &0xc0)) { *pData ^= 255; } pData++; pixels <<= 2; } while (--PixelCnt); if (xsize) { PixelCnt = 4; pixels = *(++p); goto PixelLoopXor; } break; } } //! 存储设备绘制4位直线 static void DrawBitLine4BPP(GUI_USAGE *pUsage, int x, int y, U8 const *p, int Diff, int xsize, const LCD_PIXELINDEX *pTrans) { U8 pixels; LCD_PIXELINDEX *pData; U8 PixelCnt; PixelCnt = 2-(Diff &1); pixels = (*p) << ((Diff &1) << 2); pData = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { /* * Write mode * */ case 0: /* Draw incomplete bytes to the left of center area */ if (Diff) { *pData = *(pTrans + (pixels >> 4)); pData++; xsize--; pixels = *++p; } /* Draw center area (2 pixels in one byte) */ if (xsize >= 2) { int i = xsize >> 1; xsize &= 1; do { *pData = *(pTrans + (pixels >> 4)); /* Draw 1. (left) pixel */ *(pData + 1) = *(pTrans + (pixels &15)); /* Draw 2. (right) pixel */ pData += 2; pixels = *++p; } while (--i); } /* Draw incomplete bytes to the right of center area */ if (xsize) { *pData = *(pTrans + (pixels >> 4)); } break; /* * Transparent draw mode * */ case LCD_DRAWMODE_TRANS: /* Draw incomplete bytes to the left of center area */ if (Diff) { if (pixels &0xF0) { *pData = *(pTrans + (pixels >> 4)); if (pUsage) { GUI_USAGE_AddPixel(pUsage, x, y); } } pData++; x++; xsize--; pixels = *++p; } /* Draw center area (2 pixels in one byte) */ while (xsize >= 2) { /* Draw 1. (left) pixel */ if (pixels &0xF0) { *pData = *(pTrans + (pixels >> 4)); if (pUsage) { GUI_USAGE_AddPixel(pUsage, x, y); } } /* Draw 2. (right) pixel */ if (pixels &= 15) { *(pData + 1) = *(pTrans + pixels); if (pUsage) { GUI_USAGE_AddPixel(pUsage, x + 1, y); } } pData += 2; x += 2; xsize -= 2; pixels = *++p; } /* Draw incomplete bytes to the right of center area */ if (xsize) { if (pixels >>= 4) { *pData = *(pTrans + pixels); if (pUsage) { GUI_USAGE_AddPixel(pUsage, x, y); } } } break; case LCD_DRAWMODE_XOR: PixelLoopXor: if (PixelCnt > xsize) { PixelCnt = xsize; } xsize -= PixelCnt; do { if ((pixels &0xc0)) { *pData ^= 255; } pData++; pixels <<= 4; } while (--PixelCnt); if (xsize) { PixelCnt = 2; pixels = *(++p); goto PixelLoopXor; } break; } } //! 存储设备绘制8位直线 static void DrawBitLine8BPP(GUI_USAGE *pUsage, int x, int y, U8 const *pSrc, int xsize, const LCD_PIXELINDEX *pTrans) { LCD_PIXELINDEX *pDest = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: /* Write mode */ do { *pDest = *(pTrans + *pSrc); pDest++; pSrc++; } while (--xsize); break; case LCD_DRAWMODE_TRANS: do { if (*pSrc) { *pDest = *(pTrans + *pSrc); GUI_USAGE_AddPixel(pUsage, x, y); } x++; pDest++; pSrc++; } while (--xsize); break; } } //! 存储设备绘制8位设备相关位图直线 static void DrawBitLine8BPP_DDB(GUI_USAGE *pUsage, int x, int y, U8 const *pSrc, int xsize) { LCD_PIXELINDEX *pDest; pDest = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: /* Write mode */ #if LCD_BITSPERPIXEL <=8 memcpy(pDest, pSrc, xsize); #else *pDest = *pSrc; while (--xsize) { *++pDest = *++pSrc; } #endif break; case LCD_DRAWMODE_TRANS: do { if (*pSrc) { *pDest = *pSrc; GUI_USAGE_AddPixel(pUsage, x, y); } x++; pDest++; pSrc++; } while (--xsize); break; } } #if LCD_BITSPERPIXEL >8 //! 存储设备绘制8位设备相关位图直线 static void DrawBitLine16BPP_DDB(GUI_USAGE *pUsage, int x, int y, const U16 *pSrc, int xsize) { LCD_PIXELINDEX *pDest; pDest = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x, y); switch (GUI_Context.DrawMode &(LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { case 0: /* Write mode */ memcpy(pDest, pSrc, xsize *2); break; case LCD_DRAWMODE_TRANS: do { if (*pSrc) { *pDest = *pSrc; GUI_USAGE_AddPixel(pUsage, x, y); } x++; pDest++; pSrc++; } while (--xsize); break; } } #endif ////////////////////////////////////////////////////////////////////////// //! 存储设备绘制位图 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 = (LCD_PIXELINDEX *)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 = (LCD_PIXELINDEX *)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 = (LCD_PIXELINDEX *)GUI_MEMDEV__XY2PTR(x,y); *pData = Index; if (hUsage) { GUI_USAGE* pUsage = GUI_USAGE_H2P(hUsage); GUI_USAGE_AddPixel(pUsage, x, y); } } //! 存储设备对像素进行XOR操作 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 = (LCD_PIXELINDEX *)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 = (LCD_PIXELINDEX *)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); } //! 得到调色反索引掩码 //! @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) */