www.pudn.com > uCGUI3.24-MemDev-for-3.90a.rar > GUIDEV_UsageBM.c
/*! @file GUIDEV_UsageBM.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_Protected.h" #include "GUIDebug.h" #if GUI_SUPPORT_MEMDEV extern void * _GUI_ALLOC_h2p_Lock(GUI_HMEM hMem); #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 ////////////////////////////////////////////////////////////////////////// typedef struct { GUI_USAGE Public; struct { int BytesPerLine; } Private; } GUI_USAGE_BM; static void GUI_USAGE_BM_AddPixel(GUI_USAGE *p, int x, int y) { U8 *pData; const GUI_USAGE_BM *pThis = (GUI_USAGE_BM*)p; #if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL if ((x >= pThis->Public.x0 + pThis->Public.XSize) | (x < pThis->Public.x0) | (y >= pThis->Public.y0 + pThis->Public.YSize) | (y < pThis->Public.y0)) { GUI_DEBUG_ERROROUT2("GUI_USAGE_BM_AddPixel: parameters out of bounds", x, y); } #endif x -= pThis->Public.x0; pData = (U8*)(pThis + 1); pData += (y - pThis->Public.y0) *pThis->Private.BytesPerLine; pData += x >> 3; *pData |= 0x80 >> (x &7); } static void GUI_USAGE_BM_AddHLine(GUI_USAGE *p, int x, int y, int len) { #if 0 /* Enable for the slower, but smaller version ... xxx*/ while (len-- > 0) { GUI_USAGE_BM_AddPixel(h, x++, y); } #else U8 *pData; const GUI_USAGE_BM *pThis = (GUI_USAGE_BM*)p; /* Asserts */ GUI_DEBUG_ERROROUT3_IF(x < pThis->Public.x0, "GUIDEV.c: MarkPixels: negative x offset, Act= %d, Border= %d, Clip= %d", x, pThis->Public.x0, GUI_Context.ClipRect.x0); /* Calculate pointers */ x -= pThis->Public.x0; pData = (U8*)(pThis + 1); pData += (y - pThis->Public.y0) *pThis->Private.BytesPerLine; pData += x >> 3; /* Set bits */ { int x1 = x + len - 1; /* last pixel */ int NumBytes = (x1 >> 3) - (x >> 3); U8 Mask0 = 0xff >> (x &7); U8 Mask1 = 0xff << (7-(x1 &7)); if (NumBytes == 0) { *pData |= (Mask0 &Mask1); } else { *pData++ |= Mask0; /* Mark first byte */ /* Mark middle bytes */ if (--NumBytes > 0) { memset(pData, 0xff, NumBytes); pData += NumBytes; } *pData |= Mask1; /* Mark last bytes */ } } #endif } static void GUI_USAGE_BM_Clear(GUI_USAGE *p) { GUI_USAGE_BM *pThis = (GUI_USAGE_BM*)p; memset(pThis + 1, 0, pThis->Public.YSize *pThis->Private.BytesPerLine); } static int GUI_USAGE_BM_GetNextDirty(GUI_USAGE *p, int *pxOff, int yOff) { int x = *pxOff; int xEnd; const GUI_USAGE_BM *pThis = (GUI_USAGE_BM*)p; int xSize = pThis->Public.XSize; U8 *pData = (U8*)(pThis + 1); pData += yOff * pThis->Private.BytesPerLine; pData += (x >> 3); if (x >= xSize) { return 0; } // 大括号... { /* Find first bit */ int BytesLeft = ((xSize - 1) >> 3) - (x >> 3); /* Check first byte */ U8 Data = (*pData++) << (x &7); while (Data == 0) { if (BytesLeft == 0) { return 0; } Data = *pData++; BytesLeft--; x = (x + 8) &~7; } while ((Data &0x80) == 0) { Data <<= 1; x++; } /* Find last cleared byte */ if (Data != 0xff) { /* This line is simply a speed-opt and may be eliminated */ xEnd = x; while (Data &0x40) { Data <<= 1; xEnd++; } } else { xEnd = x + 7; } if ((xEnd &7) == 7) { while (--BytesLeft >= 0) { if ((Data = *pData++) == 0xff) { xEnd += 8; } else { while (Data &0x80) { Data <<= 1; xEnd++; } break; } } } } *pxOff = x; return xEnd - x + 1; } ////////////////////////////////////////////////////////////////////////// //! void GUI_USAGE_BM_Delete(GUI_MEMDEV_Handle hDevUsage) { GUI_ALLOC_FREE(hDevUsage); } //! 存储设备使用功能(Dirty?)API函数指针表 static const tUSAGE_APIList API = { GUI_USAGE_BM_AddPixel, /* tUSAGE_AddPixel* */ GUI_USAGE_BM_AddHLine, /* tUSAGE_AddHLine* */ GUI_USAGE_BM_Clear, /* tUSAGE_Clear* */ 0, /* tUSAGE_CreateCompatible* */ GUI_USAGE_BM_Delete, /* tUSAGE_Delete* */ GUI_USAGE_BM_GetNextDirty /* tUSAGE_GetNextDirty* */ }; //! GUI_USAGE_Handle GUI_USAGE_BM_Create(int x0, int y0, int xsize, int ysize, int Flags) { int MemSize; int BytesPerLine; GUI_USAGE_Handle hMem; GUI_USE_PARA(Flags); BytesPerLine = ((xsize + 15) >> 4) << 1; /* 2 byte alignment */ MemSize = ysize * BytesPerLine + sizeof(GUI_USAGE_BM); hMem = GUI_ALLOC_AllocNoInit(MemSize); /* Check if we can alloc sufficient memory */ if (!hMem) { GUI_DEBUG_ERROROUT("GUI_USAGE_BM_Create: Too little memory"); return 0; } // 大括号... { GUI_USAGE_BM* pUsage = (GUI_USAGE_BM*)GUI_ALLOC_H2P(hMem); pUsage->Public.x0 = x0; pUsage->Public.y0 = y0; pUsage->Public.XSize = xsize; pUsage->Public.YSize = ysize; pUsage->Public.pAPI = &API; pUsage->Public.UseCnt = 1; pUsage->Private.BytesPerLine = BytesPerLine; } return hMem; } #else void GUIDEV_UsageBM(void) { /* avoid empty object files */ } #endif /* GUI_SUPPORT_MEMDEV */