www.pudn.com > uCGUI3.24-MemDev-for-3.90a.rar > GUIDEV_Measure.c


/*! @file GUIDEV_Measure.c 
 *  Implementation of measurement devices 
 *  Use a measurement device to find out the area (Rectangle) affected by a sequence of drawing operations  
 * 
 *  @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" 
 
#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_RECT rUsed; 
 
    tLCDDEV_Color2Index *pfColor2Index; 
    tLCDDEV_Index2Color *pfIndex2Color; 
    tLCDDEV_GetIndexMask*  pfGetIndexMask;//!< added by hiber 
} GUI_MEASDEV; 
 
#define GUI_MEASDEV_h2p(h) ((GUI_MEASDEV*)GUI_ALLOC_h2p(h))//!< 存储测量设备句柄到内存指针的转换 
 
////////////////////////////////////////////////////////////////////////// 
// internal routines (not part of interface table)  
 
//!  
void _MarkPixel(int x, int y) 
{ 
  GUI_MEASDEV* pDev = (GUI_MEASDEV*)(GUI_MEMDEV_H2P(GUI_Context.hDevData)); 
 
    if (x < pDev->rUsed.x0) 
    { 
        pDev->rUsed.x0 = x; 
    } 
 
    if (x > pDev->rUsed.x1) 
    { 
        pDev->rUsed.x1 = x; 
    } 
 
    if (y < pDev->rUsed.y0) 
    { 
        pDev->rUsed.y0 = y; 
    } 
 
    if (y > pDev->rUsed.y1) 
    { 
        pDev->rUsed.y1 = y; 
    } 
} 
 
//!  
void _MarkRect(int x0, int y0, int x1, int y1) 
{ 
    GUI_MEASDEV* pDev = (GUI_MEASDEV*)(GUI_MEMDEV_H2P(GUI_Context.hDevData)); 
 
    if (x0 < pDev->rUsed.x0) 
    { 
        pDev->rUsed.x0 = x0; 
    } 
 
    if (x1 > pDev->rUsed.x1) 
    { 
        pDev->rUsed.x1 = x1; 
    } 
 
    if (y1 < pDev->rUsed.y0) 
    { 
        pDev->rUsed.y0 = y0; 
    } 
 
    if (y1 > pDev->rUsed.y1) 
    { 
        pDev->rUsed.y1 = y1; 
    } 
} 
 
//! 
static void _DrawBitmap(int x0, int y0, int xsize, int ysize, int BitsPerPixel,  
                    int BytesPerLine, const U8 *pData, int Diff, const LCD_PIXELINDEX *pTrans) 
{ 
    GUI_USE_PARA(BitsPerPixel); 
    GUI_USE_PARA(BytesPerLine); 
    GUI_USE_PARA(pData); 
    GUI_USE_PARA(Diff); 
    GUI_USE_PARA(pTrans); 
 
    _MarkRect(x0, y0, x0 + xsize - 1, y0 + ysize - 1); 
} 
 
//!  
static void _DrawHLine(int x0, int y, int x1) 
{ 
    _MarkRect(x0, y, x1, y); 
} 
 
//!  
static void _DrawVLine(int x, int y0, int y1) 
{ 
    _MarkRect(x, y0, x, y1); 
} 
 
//!  
static void _SetPixelIndex(int x, int y, int Index) 
{ 
    GUI_USE_PARA(Index); 
    _MarkPixel(x, y); 
} 
 
//!  
static void _XorPixel(int x, int y) 
{ 
    _MarkPixel(x, y); 
} 
 
//!  
static unsigned int _GetPixelIndex(int x, int y) 
{ 
    GUI_USE_PARA(x); 
    GUI_USE_PARA(y); 
    return 0; 
} 
 
//!  
static void _FillRect(int x0, int y0, int x1, int y1) 
{ 
    _MarkRect(x0, y0, x1, y1); 
} 
 
//!  
static void _GetRect(LCD_RECT *pRect) 
{ 
    pRect->x0 = pRect->y0 =  - 4095; 
    pRect->x1 = pRect->y1 = 4095; 
} 
 
//!  
static unsigned int _Color2Index(LCD_COLOR Color) 
{ 
    GUI_MEASDEV * pDev = GUI_MEASDEV_h2p(GUI_Context.hDevData); 
 
    return pDev->pfColor2Index(Color); 
} 
 
//!  
static LCD_COLOR _Index2Color(int Index) 
{ 
  GUI_MEASDEV * pDev = GUI_MEASDEV_h2p(GUI_Context.hDevData); 
 
    return pDev->pfIndex2Color(Index); 
} 
 
//! 得到调色反索引掩码 
//! @note 3.24版中GUI_MEMDEV无pfGetIndexMask 
static int _GetIndexMask(void) 
{ 
    GUI_MEASDEV * pDev = GUI_MEASDEV_h2p(GUI_Context.hDevData); 
 
    return pDev->pfGetIndexMask(); 
} 
 
//!  
static void CalcPolyRect(GUI_RECT *pr, const GUI_POINT *paPoint, int NumPoints) 
{ 
    int i; 
    int xMin, xMax, yMin, yMax; 
 
    xMin = GUI_XMAX; 
    yMin = GUI_YMAX; 
    xMax = GUI_XMIN; 
    yMax = GUI_YMIN; 
 
    for (i = 0; i < NumPoints; i++) 
    { 
        int x = paPoint->x; 
        int y = paPoint->y; 
 
        if (xMin > x) 
        { 
            xMin = x; 
        } 
 
        if (xMax < x) 
        { 
            xMax = x; 
        } 
 
        if (yMin > y) 
        { 
            yMin = y; 
        } 
 
        if (yMax < y) 
        { 
            yMax = y; 
        } 
 
        paPoint++; 
    } 
 
    pr->x0 = xMin; 
    pr->x1 = xMax; 
    pr->y0 = yMin; 
    pr->y1 = yMax; 
} 
 
//!  
static void _FillPolygon(const GUI_POINT *paPoint, int NumPoints, int x0, int y0) 
{ 
    GUI_RECT r; 
 
    CalcPolyRect(&r, paPoint, NumPoints); 
    GUI_MoveRect(&r, x0, y0); 
    _MarkRect(r.x0, r.y0, r.x1, r.y1); 
} 
 
//!  
static void _FillPolygonAA(const GUI_POINT *paPoint, int NumPoints, int x0, int y0) 
{ 
    GUI_RECT r; 
    CalcPolyRect(&r, paPoint, NumPoints); 
    GUI_MoveRect(&r, x0, y0); 
 
    if (GUI_Context.AA_HiResEnable) 
    { 
        r.x0 /= GUI_Context.AA_Factor; 
        r.y0 /= GUI_Context.AA_Factor; 
        r.x1 = (r.x1 + GUI_Context.AA_Factor - 1) / GUI_Context.AA_Factor; 
        r.y1 = (r.y1 + GUI_Context.AA_Factor - 1) / GUI_Context.AA_Factor; 
    } 
 
    _MarkRect(r.x0, r.y0, r.x1, r.y1); 
} 
 
//! 设置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 
    _FillPolygon, 
    _FillPolygonAA 
}; 
 
////////////////////////////////////////////////////////////////////////// 
 
//! 
void GUI_MEASDEV_Delete(GUI_MEASDEV_Handle hMemDev) 
{ 
    /* Make sure memory device is not used */ 
    if ((GUI_Context.hDevData = hMemDev) != 0) 
    { 
        GUI_SelectLCD(); 
    } 
    GUI_ALLOC_FREE(hMemDev); 
} 
 
//! 
void GUI_MEASDEV_ClearRect(GUI_MEASDEV_Handle hMemDev) 
{ 
    if (hMemDev) 
    { 
        GUI_MEASDEV* pDevData = (GUI_MEASDEV*)GUI_ALLOC_H2P(hMemDev); 
 
        pDevData->rUsed.x0 = GUI_XMAX; 
        pDevData->rUsed.y0 = GUI_YMAX; 
        pDevData->rUsed.x1 = GUI_XMIN; 
        pDevData->rUsed.y1 = GUI_YMIN; 
    } 
} 
 
//! 
GUI_MEASDEV_Handle GUI_MEASDEV_Create(void) 
{ 
    int MemSize; 
    GUI_MEASDEV_Handle hMemDev; 
 
    MemSize = sizeof(GUI_MEASDEV); 
    hMemDev = GUI_ALLOC_AllocNoInit(MemSize); 
 
    if (hMemDev) 
    { 
        GUI_MEASDEV* pDevData = (GUI_MEASDEV*)GUI_ALLOC_H2P(hMemDev); 
 
        pDevData->pfColor2Index = GUI_Context.pDeviceAPI->pfColor2Index; 
        pDevData->pfIndex2Color = GUI_Context.pDeviceAPI->pfIndex2Color; 
        GUI_MEASDEV_ClearRect(hMemDev); 
    } 
    else 
    { 
        GUI_DEBUG_WARN("GUI_MEASDEV_Create: Alloc failed"); 
    } 
    return hMemDev; 
} 
 
 
//! @param hMem 存储设备的句柄 
void GUI_MEASDEV_Select(GUI_MEASDEV_Handle hMem) 
{ 
    if (hMem == 0) 
    { 
        GUI_SelectLCD(); 
    } 
    else 
    { 
        #if GUI_WINSUPPORT 
            WM_Deactivate(); 
        #endif 
 
        GUI_Context.hDevData = hMem; 
        GUI_Context.pDeviceAPI = &_APIList; 
        GUI_Context.pClipRect_HL = NULL; 
        LCD_SetClipRectMax(); 
    } 
} 
 
//! @param hMem 存储设备的句柄 
void GUI_MEASDEV_GetRect(GUI_MEASDEV_Handle hMem, GUI_RECT *pRect) 
{ 
    if (hMem) 
    { 
        GUI_MEASDEV* pDev = (GUI_MEASDEV*)GUI_ALLOC_H2P(hMem); 
 
        if (pRect) 
        { 
            pRect->x0 = pDev->rUsed.x0; 
            pRect->y0 = pDev->rUsed.y0; 
            pRect->x1 = pDev->rUsed.x1; 
            pRect->y1 = pDev->rUsed.y1; 
        } 
    } 
} 
 
#else 
 
void GUIDEV_Measure(void)  
{ 
    /* avoid empty object files */ 
}  
 
#endif /* GUI_MEMDEV_SUPPORT */