SAMV71 Xplained Ultra Software Package 1.3

lcd_draw.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2011, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /**
00031  * \file
00032  *
00033  * Implementation of draw function on LCD, Include draw text, image
00034  * and basic shapes (line, rectangle, circle).
00035  *
00036  */
00037 
00038 /*----------------------------------------------------------------------------
00039  *        Headers
00040  *----------------------------------------------------------------------------*/
00041 
00042 #include "board.h"
00043 
00044 #include <stdint.h>
00045 #include <string.h>
00046 #include <assert.h>
00047 
00048 /*----------------------------------------------------------------------------
00049  *        Local variables
00050  *----------------------------------------------------------------------------*/
00051 static void* gpCanvasBuffer = NULL;
00052 static uint32_t gwCanvasBufferSize;
00053 static uint32_t gwCanvasMaxWidth, gwCanvasMaxHeight;
00054 extern uint8_t ili9488_lcdMode;
00055 /*----------------------------------------------------------------------------
00056  *        Local functions
00057  *----------------------------------------------------------------------------*/
00058 
00059 /*
00060  * \brief Drar a pixel on LCD with given color, no canvas buffer needed
00061  * \param x  X-coordinate of pixel.
00062  * \param y  Y-coordinate of pixel.
00063  * \param color  Pixel color.
00064  */
00065 static void LCDD_SetPixelColor(uint32_t x, uint32_t y, uint32_t color)
00066 {
00067     uint8_t txBuf[3];
00068     ILI9488_SpiSetCursor( x, y ) ;
00069 
00070     txBuf[0] = (uint8_t)((color & 0xFF0000) >> 0x10);
00071     txBuf[1] = (uint8_t)((color & 0xFF00) >> 0x08);
00072     txBuf[2] = (uint8_t)(color & 0xFF);
00073     ILI9488_SpiSendCommand( ILI9488_CMD_MEMORY_WRITE, 
00074                             txBuf, 
00075                             NULL, 
00076                             AccessWrite,
00077                             sizeof(txBuf));
00078 }
00079 
00080 /*
00081  * \brief Fill rectangle with given color
00082  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00083  * \param rc  rectangle defines X and Y coordinate, width and height of windows.
00084  * \param dwColor color to be filled.
00085  */
00086 static void LCDD_FillSolidRect(uint16_t *pCanvasBuffer, rect rc, uint32_t dwColor )
00087 {
00088     uint32_t row, col;
00089     uint32_t w,h;
00090     
00091     //assert(gpCanvasBuffer!=NULL);
00092     w = rc.x + rc.width;
00093     w = w > gwCanvasMaxWidth ? gwCanvasMaxWidth : w;
00094     h = rc.y + rc.height;
00095     h = h > gwCanvasMaxHeight ? gwCanvasMaxHeight : h;
00096 
00097     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00098         sBGR *p_buf = gpCanvasBuffer; 
00099         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00100         if(NULL == p_buf) {
00101             for(row = rc.y; row < h; row++) {
00102                 for(col = rc.x; col < w; col++) {
00103                     LCDD_SetPixelColor(col, row, dwColor);
00104                 }
00105             }
00106             return;
00107         }
00108         //it'd better change to a DMA transfer
00109         for(row = rc.y; row < h; row++) {
00110             for(col = rc.x; col < w; col++) {
00111                 //*p_buf++ = dwColor;
00112                 p_buf[row * gwCanvasMaxWidth + col].b = dwColor&0xFF;
00113                 p_buf[row * gwCanvasMaxWidth + col].g = dwColor>>8;
00114                 p_buf[row * gwCanvasMaxWidth + col].r = dwColor>>16;
00115             }
00116         }
00117     } else {
00118         uint16_t *p_buf = gpCanvasBuffer;
00119         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00120         //it'd better change to a DMA transfer
00121         for(row = rc.y; row < h; row++) {
00122             for(col = rc.x; col < w; col++) {
00123                 p_buf[row * gwCanvasMaxWidth + col] = (uint16_t)dwColor;
00124             }
00125         }
00126     }
00127 }
00128 
00129 /*----------------------------------------------------------------------------
00130  *        Exported functions
00131  *----------------------------------------------------------------------------*/
00132 /*
00133  * \brief Update windows size.
00134  * \param rc  rectangle defines X and Y coordinate, width and height of windows.
00135  */
00136 void LCDD_SetUpdateWindowSize(rect rc)
00137 {
00138     gwCanvasMaxWidth = rc.width + 1;
00139     gwCanvasMaxHeight = rc.height + 1;
00140     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00141         ILI9488_SpiSetWindow( rc.x, rc.y, rc.width, rc.height);
00142     } else {
00143         ILI9488_EbiSetWindow( rc.x, rc.y, rc.width, rc.height);
00144     }
00145 }
00146 
00147 /*
00148  * \brief Update windows in current canvas.
00149  */
00150 void LCDD_UpdateWindow(void)
00151 {
00152     uint32_t size = 0;
00153     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00154         size = gwCanvasBufferSize / (sizeof(sBGR)) *3 ;
00155         ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00156                         (uint8_t*)gpCanvasBuffer, 0, AccessWrite, size);
00157     } else {
00158          size = gwCanvasBufferSize / sizeof(uint16_t);
00159          ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00160                         (uint16_t*)gpCanvasBuffer, 0, AccessWrite, size);
00161     }
00162  }
00163 
00164 /*
00165  * \brief Update windows in partial canvas.
00166  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00167  * \param size Size of canvas buffer.
00168  */
00169 void LCDD_UpdatePartialWindow(uint8_t* pCanvasBuffer,uint32_t size)
00170 {
00171     uint32_t cnt = 0;
00172     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00173         cnt = size/sizeof(sBGR) * 3;
00174         ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00175                         (uint8_t*)pCanvasBuffer, 0, AccessWrite, cnt);
00176     } else {
00177          cnt = size/sizeof(uint16_t);
00178          ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00179                         (uint16_t*)pCanvasBuffer, 0, AccessWrite, cnt);
00180     }
00181 }
00182 /*
00183  * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
00184  *
00185  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00186  * \param x      X-coordinate of upper-left rectangle corner.
00187  * \param y      Y-coordinate of upper-left rectangle corner.
00188  * \param width  Rectangle width in pixels.
00189  * \param height  Rectangle height in pixels.
00190  * \param color  Rectangle color.
00191  */
00192 void LCDD_DrawRectangleWithFill(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, uint32_t dwWidth, 
00193                 uint32_t dwHeight, uint32_t dwColor)
00194 {
00195     rect rc;
00196     rc.x = dwX;
00197     rc.y = dwY;
00198     rc.width = dwWidth + 1;
00199     rc.height = dwHeight + 1;
00200     LCDD_FillSolidRect(pCanvasBuffer, rc , dwColor);
00201 }
00202 
00203 /**
00204  * \brief Draws a circle on LCD, at the given coordinates.
00205  *
00206  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00207  * \param x      X-coordinate of circle centre.
00208  * \param y      Y-coordinate of circle centre.
00209  * \param r      circle radius.
00210  * \param color  circle color.
00211  */
00212 uint32_t LCDD_DrawCircle(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y, uint32_t r, uint32_t color )
00213 {
00214     signed int d; /* Decision Variable */
00215     uint32_t  curX; /* Current X Value */
00216     uint32_t  curY; /* Current Y Value */
00217 
00218     d = 3 - (r << 1);
00219     curX = 0;
00220     curY = r;
00221 
00222     while (curX <= curY) {
00223         LCDD_DrawPixel(pCanvasBuffer, x + curX, y + curY, color);
00224         LCDD_DrawPixel(pCanvasBuffer, x + curX, y - curY, color);
00225         LCDD_DrawPixel(pCanvasBuffer, x - curX, y + curY, color);
00226         LCDD_DrawPixel(pCanvasBuffer, x - curX, y - curY, color);
00227         LCDD_DrawPixel(pCanvasBuffer, x + curY, y + curX, color);
00228         LCDD_DrawPixel(pCanvasBuffer, x + curY, y - curX, color);
00229         LCDD_DrawPixel(pCanvasBuffer, x - curY, y + curX, color);
00230         LCDD_DrawPixel(pCanvasBuffer, x - curY, y - curX, color);
00231 
00232         if (d < 0) {
00233             d += (curX << 2) + 6;
00234         } else {
00235             d += ((curX - curY) << 2) + 10;
00236             curY--;
00237         }
00238         curX++;
00239     }
00240     return 0;
00241 }
00242 
00243 /*
00244  * \brief Draws a circle with fill inside on LCD, at the given coordinates.
00245  *
00246  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00247  * \param dwX      X-coordinate of upper-left rectangle corner.
00248  * \param dwY      Y-coordinate of upper-left rectangle corner.
00249  * \param dwRadius  Radius.
00250  * \param color  Rectangle color.
00251  */
00252 uint32_t LCD_DrawFilledCircle(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, 
00253                         uint32_t dwRadius, uint32_t color)
00254 {
00255     signed int d; /* Decision Variable */
00256     uint32_t dwCurX; /* Current X Value */
00257     uint32_t dwCurY; /* Current Y Value */
00258     uint32_t dwXmin, dwYmin;
00259 
00260     if (dwRadius == 0) {
00261         return 0;
00262     }
00263     d = 3 - (dwRadius << 1);
00264     dwCurX = 0;
00265     dwCurY = dwRadius;
00266 
00267     while ( dwCurX <= dwCurY ) {
00268         dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
00269         dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
00270         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, 
00271                                     dwX + dwCurX - dwXmin, 1 ,color);
00272         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, 
00273                                 dwY+dwCurY, dwX + dwCurX - dwXmin, 1,
00274                         color );
00275         dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
00276         dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
00277         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, 
00278                                 dwX + dwCurY -dwXmin , 1, color );
00279         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, 
00280                                 dwY + dwCurX, dwX+dwCurY - dwXmin, 1,
00281                         color  );
00282         if ( d < 0 ) {
00283             d += (dwCurX << 2) + 6;
00284         } else {
00285             d += ((dwCurX - dwCurY) << 2) + 10;
00286             dwCurY--;
00287         }
00288         dwCurX++;
00289     }
00290 
00291     return 0;
00292 }
00293 
00294 /**
00295  * \brief Draws a string inside a LCD buffer, at the given coordinates.
00296  *
00297  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00298  * \param x        X-coordinate of string top-left corner.
00299  * \param y        Y-coordinate of string top-left corner.
00300  * \param pString  String to display.
00301  * \param color    String color.
00302  */
00303 void LCDD_DrawString( uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, 
00304                      const uint8_t *pString, uint32_t color )
00305 {
00306     uint32_t xorg = x;
00307 
00308     while ( *pString != 0 ) {
00309         if ( *pString == '\n' ) {
00310             y += gFont.height + 2;
00311             x = xorg;
00312         } else {
00313             LCDD_DrawChar(pCanvasBuffer, x, y, *pString, color );
00314             x += gFont.width + 2;
00315         }
00316         pString++;
00317     }
00318 }
00319 
00320 /**
00321  * \brief Returns the width & height in pixels that a string will occupy on the 
00322  * screen if drawn using LCDD_DrawString.
00323  *
00324  * \param pString  String.
00325  * \param pWidth   Pointer for storing the string width (optional).
00326  * \param pHeight  Pointer for storing the string height (optional).
00327  *
00328  * \return String width in pixels.
00329  */
00330 void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth,
00331                 uint32_t *pHeight )
00332 {
00333     uint32_t width = 0;
00334     uint32_t height = gFont.height;
00335 
00336     while ( *pString != 0 ) {
00337         if ( *pString == '\n' ) {
00338             height += gFont.height + 2;
00339         } else {
00340             width += gFont.width + 2;
00341         }
00342         pString++;
00343     }
00344 
00345     if ( width > 0 ) {
00346         width -= 2;
00347     }
00348 
00349     if ( pWidth != NULL ) {
00350         *pWidth = width;
00351     }
00352 
00353     if ( pHeight != NULL ) {
00354         *pHeight = height;
00355     }
00356 }
00357 
00358 
00359 /*
00360  * \brief Performs a bit-block transfer of the color data corresponding to a 
00361  * rectangle of pixels from the given source context into destination context.
00362  *
00363  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00364  * \param dst_x   X-coordinate of source rectangle.
00365  * \param dst_y   Y-coordinate of source rectangle.
00366  * \param dst_w   Rectangle width in pixels of source rectangle.
00367  * \param dst_h   Rectangle height in pixels of source rectangle.
00368  * \param src     Pointer to the source device context.
00369  * \param src_x   X-coordinate of destination rectangle.
00370  * \param src_y   Y-coordinate of destination rectangle.
00371  * \param src_w   Rectangle width in pixels of destination rectangle.
00372  * \param src_h   Rectangle height in pixels of destination rectangle.
00373  */
00374 void LCDD_BitBlt( uint16_t* pCanvasBuffer, uint32_t dst_x,uint32_t dst_y,uint32_t dst_w,uint32_t dst_h,
00375                  const LcdColor_t *src,
00376                  uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)
00377 {
00378     uint32_t row,col;
00379     uint32_t src_row,src_col;
00380     //assert(gpCanvasBuffer!=NULL);
00381     
00382     src_h = src_h;
00383     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00384         sBGR *p_buf = gpCanvasBuffer;
00385         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00386         //it'd better change to a DMA transfer
00387         SCB_CleanInvalidateDCache();
00388         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00389             for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {
00390                 p_buf[row * gwCanvasMaxWidth+col].r = src[src_row*src_w + src_col]&0xFF;
00391                 p_buf[row * gwCanvasMaxWidth+col].g = src[src_row*src_w + src_col]>>8;
00392                 p_buf[row * gwCanvasMaxWidth+col].b = src[src_row*src_w + src_col]>>16;
00393             }
00394             memory_barrier()
00395         }
00396         memory_barrier()
00397     } else {
00398         uint16_t *p_buf = gpCanvasBuffer;
00399         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00400         //it'd better change to a DMA transfer
00401         SCB_CleanInvalidateDCache();
00402         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00403             for(src_col = src_x, col = dst_x; col < dst_w; col++,src_col++) {
00404                 p_buf[row * gwCanvasMaxWidth+col] = src[src_row*src_w + src_col];
00405             }
00406         }
00407         memory_barrier()
00408     }
00409 }
00410 
00411 
00412 /*
00413  * \brief Performs a bit-block transfer of the color data corresponding to a 
00414  * rectangle of pixels from the given source context into destination context.
00415  *
00416  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00417  * \param dst_x   X-coordinate of source rectangle.
00418  * \param dst_y   Y-coordinate of source rectangle.
00419  * \param dst_w   Rectangle width in pixels of source rectangle.
00420  * \param dst_h   Rectangle height in pixels of source rectangle.
00421  * \param src     Pointer to the source device context.
00422  * \param src_x   X-coordinate of destination rectangle.
00423  * \param src_y   Y-coordinate of destination rectangle.
00424  * \param src_w   Rectangle width in pixels of destination rectangle.
00425  * \param src_h   Rectangle height in pixels of destination rectangle.
00426  * \param alpha   alpha value.
00427  */
00428 void LCDD_BitBltAlphaBlend(uint16_t* pCanvasBuffer,
00429                         uint32_t dst_x,
00430                         uint32_t dst_y,
00431                         uint32_t dst_w,
00432                         uint32_t dst_h,
00433                         const LcdColor_t *src,
00434                         uint32_t src_x,
00435                         uint32_t src_y,
00436                         uint32_t src_w,
00437                         uint32_t src_h,
00438                         uint32_t alpha)
00439 {
00440     uint32_t row,col;
00441     uint32_t src_row,src_col;
00442     uint32_t w,h;
00443     uint32_t dst_row;
00444     uint32_t r,g,b;
00445     
00446     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00447         sBGR *p_buf = gpCanvasBuffer;
00448         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00449 
00450         //it'd better change to a DMA transfer
00451         SCB_CleanInvalidateDCache();
00452         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00453             for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {
00454                 p_buf[row *dst_w +col].r = src[src_row*src_w + src_col]&0xFF;
00455                 p_buf[row *dst_w +col].g = src[src_row*src_w + src_col]>>8;
00456                 p_buf[row *dst_w +col].b = src[src_row*src_w + src_col]>>16;
00457             }
00458         }
00459         memory_barrier()
00460     } else {
00461         uint16_t *p_buf = gpCanvasBuffer;
00462         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00463         w = src_x + src_w;
00464         h = src_y + src_h;
00465         dst_row = dst_y;
00466         p_buf += (dst_row*dst_w + dst_x);
00467         src += src_y*w + src_x;
00468         SCB_CleanInvalidateDCache();
00469         for(src_row = src_y; src_row < h; src_row++,dst_row++) {
00470             for(src_col = src_x; src_col < w; src_col++){
00471                 r = (p_buf[src_col] >> 11) * (255 - alpha) / 255 + 
00472                         (src[src_col] >> 11) * alpha / 255;
00473                 if(r > 0x1F) r = 0x1F;
00474                 g = ((p_buf[src_col] >> 5) & 0x3F) * (255 - alpha) / 255 + 
00475                         ((src[src_col] >> 5) & 0x3f) * alpha / 255;
00476                 if(g > 0x3F) g = 0x3F;
00477                 b = ((p_buf[src_col]) & 0x1F) * (255 - alpha) / 255 
00478                         + ((src[src_col]) & 0x1f) * alpha / 255;
00479                 if(b > 0x1F) b = 0x1F;   
00480                 p_buf[src_col] = ((r & 0x1F) << 11)|((g & 0x3F) << 5)|( b & 0x1F);
00481             }
00482             p_buf += dst_w;
00483             src += w;
00484         }
00485         memory_barrier()
00486     }
00487 }
00488 
00489 /*
00490  * \brief Draw a raw image at given position on LCD.
00491  *
00492  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00493  * \param dwX       X-coordinate of image start.
00494  * \param dwY       Y-coordinate of image start.
00495  * \param pImage    Image buffer.
00496  * \param width     Image width.
00497  * \param height    Image height.
00498  */
00499  void LCDD_DrawImage(uint16_t* pCanvasBuffer, uint32_t dwX, uint32_t dwY, 
00500                     const LcdColor_t *pImage, uint32_t dwWidth, uint32_t dwHeight )
00501 {
00502     /* Determine the refresh window area */
00503     /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
00504     //CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);
00505 
00506     LCDD_BitBlt(pCanvasBuffer, dwX, dwY, dwWidth, dwHeight,
00507                 pImage, 0, 0, dwWidth - dwX, dwHeight - dwY);
00508 }
00509 
00510 /**
00511  * \brief Draw a pixel on LCD of given color.
00512  *
00513  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00514  * \param x  X-coordinate of pixel.
00515  * \param y  Y-coordinate of pixel.
00516  * \param color  Pixel color.
00517  */
00518 void LCDD_DrawPixel(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, uint32_t color )
00519 {
00520     //assert(gpCanvasBuffer!=NULL);
00521     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00522         sBGR *p_buf = gpCanvasBuffer;
00523         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00524         if(NULL == p_buf){
00525             LCDD_SetPixelColor(x, y, color);
00526             return;
00527         }
00528         p_buf += y * gwCanvasMaxWidth;
00529         p_buf += x;
00530         p_buf->b = color&0xFF;
00531         p_buf->g = color>>8;
00532         p_buf->r = color>>16;
00533         p_buf++;
00534         memory_barrier()
00535     } else {
00536         uint16_t *p_buf = gpCanvasBuffer;
00537         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00538         p_buf += y * gwCanvasMaxWidth;
00539         p_buf += x;
00540         *p_buf = (uint16_t)color;
00541     }
00542 }
00543 
00544 /*
00545  * \brief Draw a line on LCD, horizontal and vertical line are supported.
00546  *
00547  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00548  * \param dwX1   X-coordinate of line start.
00549  * \param dwY1   Y-coordinate of line start.
00550  * \param dwX2   X-coordinate of line end.
00551  * \param dwY2   Y-coordinate of line end.
00552  * \param color  Pixel color.
00553  */
00554 void LCDD_DrawLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, 
00555                 uint32_t dwX2, uint32_t dwY2 , uint32_t color )
00556 {
00557     if (( dwY1 == dwY2 ) || (dwX1 == dwX2)) {
00558         //LCDD_DrawRectangleWithFill( dwX1, dwY1, dwX2, dwY2, color );
00559         LCDD_DrawStraightLine(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2, color );
00560     } else {
00561         LCDD_DrawLineBresenham(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2 , color);
00562     }
00563 }
00564 
00565 void LCDD_DrawStraightLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, 
00566                         uint32_t dwX2, uint32_t dwY2 , uint32_t color )
00567 {
00568     uint32_t x,y;
00569     uint32_t tmp;
00570 
00571     if(dwY1 > dwY2)
00572     {
00573         tmp = dwY1;
00574         dwY1 = dwY2;
00575         dwY2 = tmp;
00576     }
00577     if(dwX1 > dwX2)
00578     {
00579         tmp = dwX1;
00580         dwX1 = dwX2;
00581         dwX2 = tmp;
00582     }
00583     for(y = dwY1; y<=dwY2; y++)
00584     {
00585         for(x=dwX1;x<=dwX2;x++)
00586         {
00587             LCDD_DrawPixel(pCanvasBuffer,  x , y , color);
00588         }
00589     }
00590 }
00591 
00592 /*
00593  * \brief Draw a line on LCD, which is not horizontal or vertical.
00594  *
00595  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00596  * \param dwX1    X-coordinate of line start.
00597  * \param dwY1    Y-coordinate of line start.
00598  * \param dwX2    X-coordinate of line end.
00599  * \param dwY2    Y-coordinate of line end.
00600  * \param color   pixel color.
00601  */
00602 uint32_t LCDD_DrawLineBresenham(uint16_t* pCanvasBuffer, uint32_t dwX1, 
00603                 uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color)
00604 {
00605     int dx, dy;
00606     int i;
00607     int xinc, yinc, cumul;
00608     int x, y;
00609 
00610     x = dwX1;
00611     y = dwY1;
00612     dx = dwX2 - dwX1;
00613     dy = dwY2 - dwY1;
00614 
00615     xinc = ( dx > 0 ) ? 1 : -1;
00616     yinc = ( dy > 0 ) ? 1 : -1;
00617     dx = ( dx > 0 ) ? dx : -dx;
00618     dy = ( dy > 0 ) ? dy : -dy;
00619 
00620     LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00621 
00622     if ( dx > dy ) {
00623         cumul = dx / 2;
00624         for ( i = 1; i <= dx; i++ ) {
00625             x += xinc;
00626             cumul += dy;
00627 
00628             if ( cumul >= dx ) {
00629                 cumul -= dx;
00630                 y += yinc;
00631             }
00632             LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00633         }
00634     } else {
00635         cumul = dy / 2;
00636         for ( i = 1; i <= dy; i++ ) {
00637             y += yinc;
00638             cumul += dx;
00639 
00640             if ( cumul >= dy ) {
00641                 cumul -= dy;
00642                 x += xinc;
00643             }
00644             LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00645         }
00646     }
00647 
00648     return 0;
00649 }
00650 
00651 /*
00652  * \brief Draws a rectangle on LCD, at the given coordinates.
00653  *
00654  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00655  * \param x      X-coordinate of upper-left rectangle corner.
00656  * \param y      Y-coordinate of upper-left rectangle corner.
00657  * \param width  Rectangle width in pixels.
00658  * \param height Rectangle height in pixels.
00659  * \param color  Rectangle color.
00660  */
00661 void LCDD_DrawRectangle(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, 
00662                     uint32_t width, uint32_t height, uint32_t color )
00663 {
00664     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, width, 1, color);
00665     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, 1, height, color);
00666 
00667     LCDD_DrawRectangleWithFill(pCanvasBuffer, x + width , y, 1, height, color);
00668     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y + height, width, 1, color);
00669 }
00670 
00671 /*
00672  * \brief Set buffer for pCanvas.
00673  *
00674  * \param pCanvasBuffer  Pointer of external buffer.
00675  * \param wBufferSize   Size of buffer.
00676  */
00677 void LCDD_SetCavasBuffer( void* pCanvasBuffer, uint32_t wBufferSize)
00678 {
00679     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00680         gpCanvasBuffer = (sBGR*)pCanvasBuffer;
00681         gwCanvasBufferSize = wBufferSize;
00682     } else {
00683         gpCanvasBuffer = (uint16_t*)pCanvasBuffer;
00684         gwCanvasBufferSize = wBufferSize;
00685     }
00686 }
00687 
00688 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines