GUIDEV.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:25k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : GUIDev.C
  16. Purpose     : Implementation of memory devices
  17. ---------------------------END-OF-HEADER------------------------------
  18. */
  19. #include <string.h>
  20. #include "GUI_Private.H"
  21. #include "GUIDebug.h"
  22. /* Memory device capabilities are compiled only if support for them is enabled.*/ 
  23. #if GUI_SUPPORT_MEMDEV
  24. /*
  25.         *********************************************************
  26.         *                                                       *
  27.         *                Macros                                 *
  28.         *                                                       *
  29.         *********************************************************
  30. */
  31. #define POS_AUTO -4095   /* Position value for auto-pos */
  32. /*
  33.   ********************************************************************
  34.   *
  35.   *                  ID translation table
  36.   *
  37.   ********************************************************************
  38. This table contains 0, 1, 2, ... and serves as translation table for DDBs
  39. */
  40. #define INTS(Base)  Base+0,Base+1,Base+2,Base+3,Base+4,Base+5,   
  41.                     Base+6,Base+7,Base+8,Base+9,Base+10,Base+11, 
  42.                     Base+12,Base+13,Base+14,Base+15
  43. static const LCD_PIXELINDEX aID[] = {
  44.   INTS(0)
  45. };
  46. /*
  47.         *********************************************************
  48.         *                                                       *
  49.         *           internal routines                           *
  50.         *                                                       *
  51. *     (not part of interface table)                     *
  52.         *                                                       *
  53.         *********************************************************
  54. */
  55. LCD_PIXELINDEX* GUI_MEMDEV_XY2PTR(int x,int y) {
  56.   GUI_MEMDEV* pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  57.   U8 *pData = (U8*)(pDev+1);
  58.   #if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
  59.     if ((x >= pDev->x0+pDev->XSize) | (x<pDev->x0) | (y >= pDev->y0+pDev->YSize) | (y<pDev->y0)) {
  60.       GUI_DEBUG_ERROROUT2("GUI_MEMDEV_XY2PTR: parameters out of bounds",x,y);
  61.     }
  62.   #endif
  63.   pData += (y- pDev->y0) * pDev->BytesPerLine;
  64.   return ((LCD_PIXELINDEX*)pData) + x - pDev->x0;
  65. }
  66. /*
  67.         *********************************************************
  68.         *                                                       *
  69.         *          Draw Bitmap 1 BPP                            *
  70.         *                                                       *
  71.         *********************************************************
  72. */
  73. static void  DrawBitLine1BPP(GUI_USAGE* pUsage, int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  74.   LCD_PIXELINDEX pixels;
  75.   LCD_PIXELINDEX Index0 = *(pTrans+0);
  76.   LCD_PIXELINDEX Index1 = *(pTrans+1);
  77.   LCD_PIXELINDEX* pData;
  78.   U8  PixelCnt;
  79.   GUI_MEMDEV* pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  80.   PixelCnt = 8- (Diff&7);
  81.   pixels = (*p) << (Diff&7);
  82.   pData = GUI_MEMDEV_XY2PTR(x,y);
  83.   GUI_DEBUG_ERROROUT3_IF( x < pDev->x0, "GUIDEV.c: DrawBitLine1BPP, Act= %d, Border= %d, Clip= %d"
  84.                     ,x,pDev->x0, GUI_Context.ClipRect.x0);
  85.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  86.   case 0:    /* Write mode */
  87.   PixelLoopWrite:
  88.     if (PixelCnt>xsize)
  89.       PixelCnt =xsize;
  90.     xsize -= PixelCnt;
  91.     do {
  92.       *pData++ = (pixels&0x80) ? Index1 : Index0;
  93.       pixels<<=1;
  94.     } while (--PixelCnt);
  95.     if (xsize) {
  96.       PixelCnt=8;
  97.       pixels = *(++p);
  98.       goto PixelLoopWrite;
  99.     }
  100.     break;
  101.   case LCD_DRAWMODE_TRANS:
  102.   PixelLoopTrans:
  103.     if (PixelCnt>xsize)
  104.       PixelCnt =xsize;
  105.     xsize -= PixelCnt;
  106.     do {
  107.       if ((pixels&0x80)) {
  108.         if (pUsage)
  109.           GUI_USAGE_AddPixel(pUsage, x,y);
  110.         *pData = Index1;
  111.       }
  112.       x++;
  113.       pData++;
  114.       pixels<<=1;
  115.     } while (--PixelCnt);
  116.     if (xsize) {
  117.       PixelCnt=8;
  118.       pixels = *(++p);
  119.       goto PixelLoopTrans;
  120.     }
  121.     break;
  122.   case LCD_DRAWMODE_XOR:;
  123.   PixelLoopXor:
  124.     if (PixelCnt>xsize)
  125.       PixelCnt =xsize;
  126.     xsize -= PixelCnt;
  127.     do {
  128.       if ((pixels&0x80))
  129.         *pData = pDev->NumColors - 1 - *pData;
  130.       pData++;
  131.       pixels<<=1;
  132.     } while (--PixelCnt);
  133.     if (xsize) {
  134.       PixelCnt=8;
  135.       pixels = *(++p);
  136.       goto PixelLoopXor;
  137.     }
  138.     break;
  139.   }
  140. }
  141. /*
  142.         *********************************************************
  143.         *                                                       *
  144.         *          Draw Bitmap 2 BPP                            *
  145.         *                                                       *
  146.         *********************************************************
  147. */
  148. static void  DrawBitLine2BPP(GUI_USAGE* pUsage, int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  149.   U8 pixels;
  150.   U8  PixelCnt;
  151.   LCD_PIXELINDEX* pData;
  152.   PixelCnt = 4- (Diff&3);
  153.   pixels = (*p) << ((Diff&3)<<1);
  154.   pData = GUI_MEMDEV_XY2PTR(x,y);
  155.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  156.   case 0:    /* Write mode */
  157.   PixelLoopWrite:
  158.     if (PixelCnt>xsize) {
  159.       PixelCnt =xsize;
  160.     }
  161.     xsize -= PixelCnt;
  162.     do {
  163.       *pData++ = *(pTrans + (pixels>>6));
  164.       pixels<<=2;
  165.     } while (--PixelCnt);
  166.     if (xsize) {
  167.       PixelCnt=4;
  168.       pixels = *(++p);
  169.       goto PixelLoopWrite;
  170.     }
  171.     break;
  172.   case LCD_DRAWMODE_TRANS:
  173.   PixelLoopTrans:
  174.     if (PixelCnt>xsize)
  175.       PixelCnt =xsize;
  176.     xsize -= PixelCnt;
  177.     do {
  178.       if (pixels&0xc0) {
  179.         *pData = *(pTrans + (pixels>>6));
  180.         GUI_USAGE_AddPixel(pUsage, x,y);
  181.       }
  182.       pData++;
  183.       pixels<<=2;
  184.     } while (--PixelCnt);
  185.     if (xsize) {
  186.       PixelCnt=4;
  187.       pixels = *(++p);
  188.       goto PixelLoopTrans;
  189.     }
  190.     break;
  191.   case LCD_DRAWMODE_XOR:;
  192.   PixelLoopXor:
  193.     if (PixelCnt>xsize)
  194.       PixelCnt =xsize;
  195.     xsize -= PixelCnt;
  196.     do {
  197.       if ((pixels&0xc0))
  198.         *pData ^= 255;
  199.       pData++;
  200.       pixels<<=2;
  201.     } while (--PixelCnt);
  202.     if (xsize) {
  203.       PixelCnt=4;
  204.       pixels = *(++p);
  205.       goto PixelLoopXor;
  206.     }
  207.     break;
  208.   }
  209. }
  210. /*
  211.         *********************************************************
  212.         *                                                       *
  213.         *          Draw Bitmap 4 BPP                            *
  214.         *                                                       *
  215.         *********************************************************
  216. */
  217. static void  DrawBitLine4BPP(GUI_USAGE* pUsage, int x, int y, U8 const*p, int Diff, int xsize, const LCD_PIXELINDEX*pTrans) {
  218.   U8 pixels;
  219.   LCD_PIXELINDEX* pData;
  220.   U8  PixelCnt;
  221.   PixelCnt = 2- (Diff&1);
  222.   pixels = (*p) << ((Diff&1)<<2);
  223.   pData = GUI_MEMDEV_XY2PTR(x,y);
  224.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  225. /*
  226.           * Write mode *
  227. */
  228.   case 0:
  229.     /* Draw incomplete bytes to the left of center area */
  230.     if (Diff) {
  231.       *pData = *(pTrans + (pixels >>4));
  232.       pData++;
  233.       xsize--;
  234.       pixels = *++p;
  235.     }
  236.     /* Draw center area (2 pixels in one byte) */
  237.     if (xsize >= 2) {
  238.       int i = xsize>>1;
  239.       xsize &= 1;
  240.       do {
  241.         *pData     = *(pTrans + (pixels>>4));   /* Draw 1. (left) pixel */
  242.         *(pData+1) = *(pTrans + (pixels&15));   /* Draw 2. (right) pixel */
  243.         pData +=2;
  244.         pixels = *++p;
  245.       } while (--i);
  246.     }
  247.     /* Draw incomplete bytes to the right of center area */
  248.     if (xsize) {
  249.       *pData = * (pTrans + (pixels >> 4));
  250.     }
  251.     break;
  252. /*
  253.           * Transparent draw mode *
  254. */
  255.   case LCD_DRAWMODE_TRANS:
  256.     /* Draw incomplete bytes to the left of center area */
  257.     if (Diff) {
  258.       if (pixels&0xF0) {
  259.         *pData = *(pTrans + (pixels>>4));
  260.         if (pUsage)
  261.           GUI_USAGE_AddPixel(pUsage, x,y);
  262.       }
  263.       pData++;
  264.       x++;
  265.       xsize--;
  266.       pixels = *++p;
  267.     }
  268.     /* Draw center area (2 pixels in one byte) */
  269.     while (xsize >= 2) {
  270.       /* Draw 1. (left) pixel */
  271.       if (pixels&0xF0) {
  272.         *pData = *(pTrans + (pixels>>4));
  273.         if (pUsage)
  274.           GUI_USAGE_AddPixel(pUsage, x,y);
  275.       }
  276.       /* Draw 2. (right) pixel */
  277.       if (pixels &= 15) {
  278.         *(pData+1) = *(pTrans + pixels);
  279.         if (pUsage)
  280.           GUI_USAGE_AddPixel(pUsage, x+1,y);
  281.       }
  282.       pData +=2;
  283.       x+=2;
  284.       xsize-=2;
  285.       pixels = *++p;
  286.     }
  287.     /* Draw incomplete bytes to the right of center area */
  288.     if (xsize) {
  289.       if (pixels >>= 4) {
  290.         *pData = *(pTrans + pixels);
  291.         if (pUsage)
  292.           GUI_USAGE_AddPixel(pUsage, x,y);
  293.       }
  294.     }
  295.     break;
  296.   case LCD_DRAWMODE_XOR:;
  297.   PixelLoopXor:
  298.     if (PixelCnt>xsize)
  299.       PixelCnt =xsize;
  300.     xsize -= PixelCnt;
  301.     do {
  302.       if ((pixels&0xc0))
  303.         *pData ^= 255;
  304.       pData++;
  305.       pixels<<=4;
  306.     } while (--PixelCnt);
  307.     if (xsize) {
  308.       PixelCnt=2;
  309.       pixels = *(++p);
  310.       goto PixelLoopXor;
  311.     }
  312.     break;
  313.   }
  314. }
  315. /*
  316.         *********************************************************
  317.         *                                                       *
  318.         *          Draw Bitmap 8 BPP Trans                      *
  319.         *                                                       *
  320.         *********************************************************
  321. */
  322. static void  DrawBitLine8BPP(GUI_USAGE* pUsage, int x, int y, U8 const*pSrc, int xsize, const LCD_PIXELINDEX*pTrans) {
  323.   LCD_PIXELINDEX* pDest;
  324.   pDest = GUI_MEMDEV_XY2PTR(x,y);
  325.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  326.   case 0:    /* Write mode */
  327.     do {
  328.       *pDest = *(pTrans + *pSrc);
  329.       pDest++;
  330.       pSrc++;
  331.     } while (--xsize);
  332.     break;
  333.   case LCD_DRAWMODE_TRANS:
  334.     do {
  335.       if (*pSrc) {
  336.         *pDest = *(pTrans + *pSrc);
  337.         GUI_USAGE_AddPixel(pUsage, x,y);
  338.       }
  339.       x++;
  340.       pDest++;
  341.       pSrc++;
  342.     } while (--xsize);
  343.     break;
  344.   }
  345. }
  346. /*
  347.         *********************************************************
  348.         *                                                       *
  349.         *          Draw Bitmap 8 BPP No Trans                   *
  350.         *                                                       *
  351.         *********************************************************
  352. */
  353. static void  DrawBitLine8BPP_DDB(GUI_USAGE* pUsage, int x, int y, U8 const*pSrc, int xsize) {
  354.   LCD_PIXELINDEX* pDest;
  355.   pDest = GUI_MEMDEV_XY2PTR(x,y);
  356.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  357.   case 0:    /* Write mode */
  358.     #if LCD_BITSPERPIXEL <=8
  359.       memcpy(pDest, pSrc, xsize);
  360.     #else
  361.       *pDest = *pSrc;
  362.       while (--xsize) {
  363.         *++pDest = *++pSrc;
  364.       }
  365.     #endif
  366.     break;
  367.   case LCD_DRAWMODE_TRANS:
  368.     do {
  369.       if (*pSrc) {
  370.         *pDest = *pSrc;
  371.         GUI_USAGE_AddPixel(pUsage, x,y);
  372.       }
  373.       x++;
  374.       pDest++;
  375.       pSrc++;
  376.     } while (--xsize);
  377.     break;
  378.   }
  379. }
  380. /********************************************************
  381. *
  382. *          Draw Bitmap 16 BPP DDB
  383. *
  384. *********************************************************
  385. */
  386. #if LCD_BITSPERPIXEL >8
  387. static void  DrawBitLine16BPP_DDB(GUI_USAGE* pUsage, int x, int y, const U16 *pSrc, int xsize) {
  388.   LCD_PIXELINDEX* pDest;
  389.   pDest = GUI_MEMDEV_XY2PTR(x,y);
  390.   switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {
  391.   case 0:    /* Write mode */
  392.     memcpy(pDest, pSrc, xsize*2);
  393.     break;
  394.   case LCD_DRAWMODE_TRANS:
  395.     do {
  396.       if (*pSrc) {
  397.         *pDest = *pSrc;
  398.         GUI_USAGE_AddPixel(pUsage, x,y);
  399.       }
  400.       x++;
  401.       pDest++;
  402.       pSrc++;
  403.     } while (--xsize);
  404.     break;
  405.   }
  406. }
  407. #endif
  408. /*
  409.         *********************************************************
  410.         *                                                       *
  411.         *         Universal draw Bitmap routine                 *
  412.         *                                                       *
  413.         *********************************************************
  414. */
  415. static void _DrawBitmap   (int x0, int y0,
  416.                        int xsize, int ysize,
  417.                        int BitsPerPixel, 
  418.                        int BytesPerLine,
  419.                        const U8* pData, int Diff,
  420.                        const LCD_PIXELINDEX* pTrans)
  421. {
  422.   int i;
  423.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  424.   GUI_USAGE* pUsage = (pDev->hUsage) ? GUI_USAGE_h2p(pDev->hUsage) : 0;
  425.   /* Mark all affected pixels dirty unless transparency is set */
  426.   if (pUsage) {
  427.     if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) ==0) {
  428.       for (i=0; i<ysize; i++) {
  429.         GUI_USAGE_AddHLine(pUsage, x0+Diff,y0+i,xsize);
  430.       }
  431.     }
  432.   }
  433.   /* Handle 8 bpp bitmaps seperately as we have different routine bitmaps with or without palette */
  434.   x0+=Diff;
  435.   /* handle 16 bpp bitmaps in high color modes, but only without palette */
  436.   #if LCD_BITSPERPIXEL >8
  437.     if (BitsPerPixel==16) {
  438.       for (i=0; i<ysize; i++) {
  439.         DrawBitLine16BPP_DDB(pUsage, x0, i+y0, (U16*)pData, xsize);
  440.         pData += BytesPerLine;
  441.       }
  442.       return;
  443.     }
  444.   #endif
  445.   /* handle 8 bpp bitmaps */
  446.   if (BitsPerPixel==8) {
  447.     for (i=0; i<ysize; i++) {
  448.       if (pTrans) {
  449.         DrawBitLine8BPP(pUsage, x0, i+y0, pData, xsize, pTrans);
  450.       } else {
  451.         DrawBitLine8BPP_DDB(pUsage, x0, i+y0, pData, xsize);
  452.       }
  453.       pData += BytesPerLine;
  454.     }
  455.     return;
  456.   }
  457.   /* Use aID for bitmaps without palette */
  458.   if (!pTrans) {
  459.     pTrans = aID;
  460.   }
  461.   for (i=0; i<ysize; i++) {
  462.     switch (BitsPerPixel) {
  463.     case 1:
  464.       DrawBitLine1BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
  465.       break;
  466.     case 2:
  467.       DrawBitLine2BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
  468.       break;
  469.     case 4:
  470.       DrawBitLine4BPP(pUsage, x0, i+y0, pData, Diff, xsize, pTrans);
  471.       break;
  472.     }
  473.     pData += BytesPerLine;
  474.   }
  475. }
  476. static void _DrawHLine    (int x0, int y,  int x1) {
  477.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  478.   GUI_USAGE_h hUsage = pDev->hUsage; 
  479.   if (hUsage)
  480.     GUI_USAGE_AddHLine(GUI_USAGE_h2p(hUsage), x0,y,x1-x0+1);
  481.   {
  482.     int len = x1-x0+1;
  483.     LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x0,y);
  484.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
  485.       int NumColorsM1 = pDev->NumColors-1;
  486.       do {
  487.         *pData = NumColorsM1 - *pData;
  488.         pData++;
  489.       } while (--len);
  490.     } else {  /* Fill */
  491.       #if LCD_BITSPERPIXEL <=8
  492.         memset (pData, LCD_COLORINDEX, len);
  493.       #else
  494.         *pData = LCD_COLORINDEX;   /* We write at least one pixel, so this is permitted ...
  495.                                   (speed optimization) */
  496.         while (--len) {
  497.           *++pData = LCD_COLORINDEX;
  498.         }
  499.       #endif
  500.     }
  501.   }
  502. }
  503. static void _DrawVLine    (int x , int y0,  int y1) {
  504.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  505.   GUI_USAGE_h hUsage = pDev->hUsage; 
  506.   GUI_USAGE*  pUsage = hUsage ? GUI_USAGE_h2p(hUsage) : NULL;
  507.   int NumColorsM1 = pDev->NumColors-1;
  508.   LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y0);
  509.   do {
  510.     if (hUsage)
  511.       GUI_USAGE_AddPixel(pUsage, x,y0);
  512.     if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR)
  513.       *pData = NumColorsM1 - *pData;
  514.     else
  515.       *pData = LCD_COLORINDEX;
  516.     #if LCD_BITSPERPIXEL <= 8
  517.       pData += pDev->BytesPerLine;
  518.     #else
  519.       pData += pDev->BytesPerLine>>1;
  520.     #endif
  521.   } while (++y0<=y1);
  522. }
  523. static void _SetPixelIndex (int x, int y, int Index){
  524.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  525.   GUI_USAGE_h hUsage = pDev->hUsage; 
  526.   LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
  527.   *pData = Index;
  528.   if (hUsage) {
  529.     GUI_USAGE*  pUsage = GUI_USAGE_h2p(hUsage);
  530.     GUI_USAGE_AddPixel(pUsage, x,y);
  531.   }
  532. }
  533. static void _XorPixel (int x, int y) {
  534.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  535.   GUI_USAGE_h hUsage = pDev->hUsage; 
  536.   LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
  537.   *pData = pDev->NumColors - 1-*pData;
  538.   if (hUsage) {
  539.     GUI_USAGE*  pUsage = GUI_USAGE_h2p(hUsage);
  540.     GUI_USAGE_AddPixel(pUsage, x,y);
  541.   }
  542. }
  543. static unsigned int _GetPixelIndex (int x, int y){
  544.   LCD_PIXELINDEX* pData = GUI_MEMDEV_XY2PTR(x,y);
  545.   return *pData;
  546. }
  547. static void _FillRect     (int x0, int y0, int x1, int y1){
  548.   for (; y0 <= y1; y0++) {
  549.     _DrawHLine(x0,y0, x1);
  550.   }
  551. }
  552. static void _GetRect  (GUI_RECT* pRect) {
  553.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  554.   pRect->x0 = pDev->x0;
  555.   pRect->y0 = pDev->y0;
  556.   pRect->x1 = pDev->x0 + pDev->XSize-1;
  557.   pRect->y1 = pDev->y0 + pDev->YSize-1;
  558. }
  559. static  unsigned int _Color2Index (LCD_COLOR Color) {
  560.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  561.   return pDev->pfColor2Index(Color);
  562. }
  563. static  LCD_COLOR _Index2Color (int Index) {
  564.   GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(GUI_Context.hDevData);
  565.   return pDev->pfIndex2Color(Index);
  566. }
  567. /*********************************************************************
  568. *
  569. *             Device structure
  570. *
  571. **********************************************************************
  572. */
  573. static const tLCDDEV_APIList _APIList = {
  574.   _Color2Index,
  575.   _DrawBitmap,
  576.   _DrawHLine,
  577.   _DrawVLine,
  578.   _FillRect,
  579.   _GetPixelIndex,
  580.   _GetRect,
  581.   _Index2Color,
  582.   _SetPixelIndex,
  583.   _XorPixel
  584. };
  585. /*
  586.   *********************************************************
  587.   *
  588.   *            Exported routines
  589.   *
  590.   *********************************************************
  591. */
  592. /*
  593.       *************************************************
  594.       *                                               *
  595.       *             Delete                            *
  596.       *                                               *
  597.       *************************************************
  598. */
  599. void GUI_MEMDEV_Delete(GUI_MEMDEV_Handle hMemDev) {
  600. /* Make sure memory device is not used */
  601.   GUI_LOCK();
  602.   if (hMemDev) {
  603.     GUI_MEMDEV* pDev;
  604.     if (GUI_Context.hDevData == hMemDev) {
  605.     GUI_SelectLCD();
  606.     }
  607.     pDev = GUI_MEMDEV_h2p(hMemDev);
  608.     /* Delete the associated usage device */
  609.     if (pDev->hUsage)
  610.       GUI_USAGE_DecUseCnt(pDev->hUsage);
  611.     GUI_ALLOC_FREE(hMemDev);
  612.   }
  613.   GUI_UNLOCK();
  614. }
  615. /************************************************
  616. *
  617. *             CreateEx
  618. *
  619. *************************************************
  620. */
  621. GUI_MEMDEV_Handle GUI_MEMDEV_CreateEx (int x0, int y0, int xsize, int ysize, int Flags) {
  622.   I32 MemSize;
  623.   GUI_USAGE_Handle hUsage =0;
  624.   #if LCD_BITSPERPIXEL <= 8
  625.     int BytesPerLine = (( 8*xsize+15)>>4)<<1;  /* Reserve 8 bits for pixels */
  626.   #else
  627.     int BytesPerLine = ((16*xsize+15)>>4)<<1;  /* Reserve 16 bits for pixels */
  628.   #endif
  629.   GUI_MEMDEV_Handle hMemDev;
  630.   /* Calc avaliable MemSize */
  631.   MemSize = GUI_ALLOC_GetMaxSize();
  632.   if (!(Flags & GUI_MEMDEV_NOTRANS)) {
  633.     MemSize = (MemSize/4)*3;   /* We need to reserve some memory for usage object */
  634.   }
  635.   if (ysize<=0) {
  636.     int MaxLines = (MemSize-sizeof(GUI_MEMDEV))/BytesPerLine;
  637.     ysize = (MaxLines >-ysize) ? -ysize : MaxLines;
  638.   }
  639.   if (!(Flags & GUI_MEMDEV_NOTRANS)) {
  640.     /* Create the usage map */
  641.     hUsage = GUI_USAGE_BM_Create(x0, y0, xsize, ysize, 0);
  642.   }
  643.   /* Check if we can alloc sufficient memory */
  644.   if (ysize <= 0) {
  645.     GUI_DEBUG_WARN("GUI_MEMDEV_Create: Too little memory");
  646.     return 0;    
  647.   }
  648.   MemSize = ysize*BytesPerLine +sizeof(GUI_MEMDEV);
  649.   hMemDev = GUI_ALLOC_ALLOC(MemSize);
  650.   if (hMemDev) {
  651.     GUI_MEMDEV* pDevData = GUI_MEMDEV_h2p(hMemDev);
  652.     pDevData->x0    = x0;
  653.     pDevData->y0    = y0;
  654.     pDevData->XSize = xsize;
  655.     pDevData->YSize = ysize;
  656.     pDevData->NumColors = LCD_GET_NUMCOLORS();
  657.     pDevData->BytesPerLine= BytesPerLine;
  658.     pDevData->hUsage = hUsage;
  659.     pDevData->pfColor2Index = GUI_Context.pDeviceAPI->pfColor2Index;    
  660.     pDevData->pfIndex2Color = GUI_Context.pDeviceAPI->pfIndex2Color;
  661.   } else {
  662.     GUI_DEBUG_WARN("GUI_MEMDEV_Create: Alloc failed");
  663.   }
  664.   return hMemDev;
  665. }
  666. /************************************************
  667. *
  668. *             Create
  669. *
  670. *************************************************
  671. */
  672. GUI_MEMDEV_Handle GUI_MEMDEV_Create (int x0, int y0, int xsize, int ysize) {
  673.   return GUI_MEMDEV_CreateEx(x0, y0, xsize, ysize, GUI_MEMDEV_HASTRANS);
  674. }
  675. /************************************************
  676. *
  677. *             Select
  678. *
  679. *************************************************
  680. */
  681. void GUI_MEMDEV_Select(GUI_MEMDEV_Handle hMem) {
  682.   if (hMem==0) {
  683.     GUI_SelectLCD();
  684.   } else {
  685.     #if GUI_WINSUPPORT
  686.       WM_Deactivate();
  687.     #endif
  688.     /* If LCD was selected Save cliprect */
  689.     if (GUI_Context.hDevData == 0)
  690.       GUI_Context.ClipRectPrev = GUI_Context.ClipRect;
  691.     GUI_Context.hDevData = hMem;
  692.     GUI_Context.pDeviceAPI  = &_APIList;
  693.     LCD_SetClipRectMax();
  694.   }
  695. }
  696. /*
  697.       *************************************************
  698.       *                                               *
  699.       *             CopyToLCDAt                       *
  700.       *                                               *
  701.       *************************************************
  702. */
  703. #if LCD_BITSPERPIXEL <=8
  704.   #define BITSPERPIXEL 8
  705. #else
  706.   #define BITSPERPIXEL 16
  707. #endif
  708. #define BYTESPERLINE (BITSPERPIXEL/8)
  709. static void _CopyToLCDAt(GUI_MEMDEV_Handle hMem,int x, int y) {
  710.   /* Make sure the memory handle is valid */
  711.   if (!hMem) {
  712.     return;
  713.   }
  714.   {
  715.     GUI_MEMDEV * pDev = GUI_MEMDEV_h2p(hMem);
  716.     GUI_USAGE_h hUsage = pDev->hUsage; 
  717.     GUI_USAGE*  pUsage;
  718.     int YSize = pDev->YSize;
  719.     int yi;
  720.     int BytesPerLine = pDev->BytesPerLine;
  721.     U8 * pData = (U8*)(pDev+1);
  722.     if (hUsage) {
  723.       pUsage = GUI_USAGE_h2p(hUsage);
  724.       for (yi = 0; yi < YSize; yi++) {
  725.         int xOff = 0;
  726.         int XSize;
  727.         XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);
  728.         if (XSize == pDev->XSize) {
  729.           /* If the entire line is affected, calculate the number of entire lines */
  730.           int y0 = yi;
  731.           while ((GUI_USAGE_GetNextDirty(pUsage, &xOff, yi + 1)) == XSize) {
  732.             yi++;
  733.           }
  734.       LCD_DrawBitmap(x, y + y0, pDev->XSize, yi - y0 + 1,
  735.                          1, 1,
  736.                          BITSPERPIXEL,
  737.                          BytesPerLine, pData, NULL);
  738.           pData += (yi - y0 + 1) * BytesPerLine;
  739.         } else {
  740.           /* Draw the partial line which needs to be drawn */
  741.           for (; XSize; ) {
  742.             LCD_DrawBitmap(x + xOff, y + yi, XSize, 1, 
  743.                            1, 1, 
  744.                            BITSPERPIXEL, 
  745.                            BytesPerLine, pData + xOff * BYTESPERLINE, NULL);
  746.             xOff += XSize;
  747.             XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);
  748.           }
  749.           pData += BytesPerLine;
  750.         }
  751.       }
  752.     } else {
  753.   LCD_DrawBitmap(x, y, pDev->XSize, YSize,
  754.                      1, 1,
  755.                      BITSPERPIXEL,
  756.                      BytesPerLine, pData, NULL);
  757.     }
  758.   }
  759.   GUI_ALLOC_UNLOCK(hMem);
  760. }
  761. #if (GUI_WINSUPPORT)
  762. void GUI_MEMDEV_CopyToLCDAt(GUI_MEMDEV_Handle hMem, int x, int y) {
  763.   if (hMem) {
  764.     WM_LOCK(); {
  765.       GUI_MEMDEV_Handle hMemPrev = GUI_Context.hDevData;
  766.       GUI_MEMDEV* pDevData = (GUI_MEMDEV*) GUI_ALLOC_LOCK(hMem);  /* Convert to pointer */
  767.       GUI_RECT r;
  768.       /* Make sure LCD is selected as device */
  769.       if (hMemPrev) {
  770.         GUI_MEMDEV_Select(0);  /* Activate LCD */
  771.       }
  772.       if (x==POS_AUTO) {
  773.         x = pDevData->x0;
  774.         y = pDevData->y0;
  775.       }
  776.       /* Calculate rectangle */
  777.       r.x1 = (r.x0 = x) + pDevData->XSize-1;
  778.       r.y1 = (r.y0 = y) + pDevData->YSize-1;;
  779.       /* Do the drawing. WIndow manager has to be on */
  780.       WM_Activate();
  781.       WM_ITERATE_START(&r) {
  782.         _CopyToLCDAt(hMem,x,y);
  783.       } WM_ITERATE_END();
  784.       /* Reactivate previously used device */
  785.       GUI_MEMDEV_Select(hMemPrev);
  786.     } WM_UNLOCK();
  787.   }
  788. }
  789. #else
  790. void GUI_MEMDEV_CopyToLCDAt(GUI_MEMDEV_Handle hMem,int x, int y) {
  791.   GUI_MEMDEV_Handle hMemPrev = GUI_Context.hDevData;
  792.   GUI_MEMDEV* pDevData = (GUI_MEMDEV*) GUI_ALLOC_LOCK(hMem);  /* Convert to pointer */
  793.   /* Make sure LCD is selected as device */
  794.   if (hMemPrev) {
  795.     GUI_MEMDEV_Select(0);  /* Activate LCD */
  796.   }
  797.   if (x==POS_AUTO) {
  798.     x = pDevData->x0;
  799.     y = pDevData->y0;
  800.   }
  801.   _CopyToLCDAt(hMem,x,y);
  802.   /* Reactivate previously used memory device */
  803.   if (hMemPrev) {
  804.     GUI_MEMDEV_Select(hMemPrev);
  805.   }
  806. }
  807. #endif
  808. /*
  809.       *************************************************
  810.       *                                               *
  811.       *             CopyToLCD                         *
  812.       *                                               *
  813.       *************************************************
  814. */
  815. void GUI_MEMDEV_CopyToLCD(GUI_MEMDEV_Handle hMem) {
  816.   GUI_MEMDEV_CopyToLCDAt(hMem, POS_AUTO, POS_AUTO);
  817. }
  818. #else
  819. void GUIDEV(void) {}
  820. #endif /* GUI_SUPPORT_MEMDEV && (LCD_BITSPERPIXEL <= 8) */