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 */