SAMV71 Xplained Ultra Software Package 1.4

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     ILI9488_SetPixelColor(x, y, color);
00068 }
00069 
00070 /*
00071  * \brief Fill rectangle with given color
00072  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00073  * \param rc  rectangle defines X and Y coordinate, width and height of windows.
00074  * \param dwColor color to be filled.
00075  */
00076 static void LCDD_FillSolidRect(uint16_t *pCanvasBuffer, rect rc, uint32_t dwColor )
00077 {
00078     uint32_t row, col;
00079     uint32_t w,h;
00080     
00081     //assert(gpCanvasBuffer!=NULL);
00082     w = rc.x + rc.width;
00083     w = w > gwCanvasMaxWidth ? gwCanvasMaxWidth : w;
00084     h = rc.y + rc.height;
00085     h = h > gwCanvasMaxHeight ? gwCanvasMaxHeight : h;
00086 
00087     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00088         sBGR *p_buf = gpCanvasBuffer; 
00089         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00090         if(NULL == p_buf) {
00091             for(row = rc.y; row < h; row++) {
00092                 for(col = rc.x; col < w; col++) {
00093                     LCDD_SetPixelColor(col, row, dwColor);
00094                 }
00095             }
00096             return;
00097         }
00098         //it'd better change to a DMA transfer
00099         for(row = rc.y; row < h; row++) {
00100             for(col = rc.x; col < w; col++) {
00101                 //*p_buf++ = dwColor;
00102                 p_buf[row * gwCanvasMaxWidth + col].b = dwColor&0xFF;
00103                 p_buf[row * gwCanvasMaxWidth + col].g = dwColor>>8;
00104                 p_buf[row * gwCanvasMaxWidth + col].r = dwColor>>16;
00105             }
00106         }
00107     } else {
00108         uint16_t *p_buf = gpCanvasBuffer;
00109         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00110         //it'd better change to a DMA transfer
00111         for(row = rc.y; row < h; row++) {
00112             for(col = rc.x; col < w; col++) {
00113                 p_buf[row * gwCanvasMaxWidth + col] = (uint16_t)dwColor;
00114             }
00115         }
00116     }
00117 }
00118 
00119 /*----------------------------------------------------------------------------
00120  *        Exported functions
00121  *----------------------------------------------------------------------------*/
00122 /*
00123  * \brief Update windows size.
00124  * \param rc  rectangle defines X and Y coordinate, width and height of windows.
00125  */
00126 void LCDD_SetUpdateWindowSize(rect rc)
00127 {
00128     gwCanvasMaxWidth = rc.width + 1;
00129     gwCanvasMaxHeight = rc.height + 1;
00130     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00131         ILI9488_SpiSetWindow( rc.x, rc.y, rc.width, rc.height);
00132     } else {
00133         ILI9488_EbiSetWindow( rc.x, rc.y, rc.width, rc.height);
00134     }
00135 }
00136 
00137 /*
00138  * \brief Update windows in current canvas.
00139  */
00140 void LCDD_UpdateWindow(void)
00141 {
00142     uint32_t size = 0;
00143     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00144         size = gwCanvasBufferSize / (sizeof(sBGR)) *3 ;
00145         ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00146                         (uint8_t*)gpCanvasBuffer, 0, AccessWrite, size);
00147     } else {
00148          size = gwCanvasBufferSize / sizeof(uint16_t);
00149          ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00150                         (uint16_t*)gpCanvasBuffer, 0, AccessWrite, size);
00151     }
00152  }
00153 
00154 /*
00155  * \brief Update windows in partial canvas.
00156  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00157  * \param size Size of canvas buffer.
00158  */
00159 void LCDD_UpdatePartialWindow(uint8_t* pCanvasBuffer,uint32_t size)
00160 {
00161     uint32_t cnt = 0;
00162     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00163         cnt = size/sizeof(sBGR) * 3;
00164         ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00165                         (uint8_t*)pCanvasBuffer, 0, AccessWrite, cnt);
00166     } else {
00167          cnt = size/sizeof(uint16_t);
00168          ILI9488_EbiSendCommand(ILI9488_CMD_MEMORY_WRITE, 
00169                         (uint16_t*)pCanvasBuffer, 0, AccessWrite, cnt);
00170     }
00171 }
00172 /*
00173  * \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
00174  *
00175  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00176  * \param x      X-coordinate of upper-left rectangle corner.
00177  * \param y      Y-coordinate of upper-left rectangle corner.
00178  * \param width  Rectangle width in pixels.
00179  * \param height  Rectangle height in pixels.
00180  * \param color  Rectangle color.
00181  */
00182 void LCDD_DrawRectangleWithFill(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, uint32_t dwWidth, 
00183                 uint32_t dwHeight, uint32_t dwColor)
00184 {
00185     rect rc;
00186     rc.x = dwX;
00187     rc.y = dwY;
00188     rc.width = dwWidth + 1;
00189     rc.height = dwHeight + 1;
00190     LCDD_FillSolidRect(pCanvasBuffer, rc , dwColor);
00191 }
00192 
00193 /**
00194  * \brief Draws a circle on LCD, at the given coordinates.
00195  *
00196  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00197  * \param x      X-coordinate of circle centre.
00198  * \param y      Y-coordinate of circle centre.
00199  * \param r      circle radius.
00200  * \param color  circle color.
00201  */
00202 uint32_t LCDD_DrawCircle(uint16_t *pCanvasBuffer, uint32_t x, uint32_t y, uint32_t r, uint32_t color )
00203 {
00204     signed int d; /* Decision Variable */
00205     uint32_t  curX; /* Current X Value */
00206     uint32_t  curY; /* Current Y Value */
00207 
00208     d = 3 - (r << 1);
00209     curX = 0;
00210     curY = r;
00211 
00212     while (curX <= curY) {
00213         LCDD_DrawPixel(pCanvasBuffer, x + curX, y + curY, color);
00214         LCDD_DrawPixel(pCanvasBuffer, x + curX, y - curY, color);
00215         LCDD_DrawPixel(pCanvasBuffer, x - curX, y + curY, color);
00216         LCDD_DrawPixel(pCanvasBuffer, x - curX, y - curY, color);
00217         LCDD_DrawPixel(pCanvasBuffer, x + curY, y + curX, color);
00218         LCDD_DrawPixel(pCanvasBuffer, x + curY, y - curX, color);
00219         LCDD_DrawPixel(pCanvasBuffer, x - curY, y + curX, color);
00220         LCDD_DrawPixel(pCanvasBuffer, x - curY, y - curX, color);
00221 
00222         if (d < 0) {
00223             d += (curX << 2) + 6;
00224         } else {
00225             d += ((curX - curY) << 2) + 10;
00226             curY--;
00227         }
00228         curX++;
00229     }
00230     return 0;
00231 }
00232 
00233 /*
00234  * \brief Draws a circle with fill inside on LCD, at the given coordinates.
00235  *
00236  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00237  * \param dwX      X-coordinate of upper-left rectangle corner.
00238  * \param dwY      Y-coordinate of upper-left rectangle corner.
00239  * \param dwRadius  Radius.
00240  * \param color  Rectangle color.
00241  */
00242 uint32_t LCD_DrawFilledCircle(uint16_t *pCanvasBuffer, uint32_t dwX, uint32_t dwY, 
00243                         uint32_t dwRadius, uint32_t color)
00244 {
00245     signed int d; /* Decision Variable */
00246     uint32_t dwCurX; /* Current X Value */
00247     uint32_t dwCurY; /* Current Y Value */
00248     uint32_t dwXmin, dwYmin;
00249 
00250     if (dwRadius == 0) {
00251         return 0;
00252     }
00253     d = 3 - (dwRadius << 1);
00254     dwCurX = 0;
00255     dwCurY = dwRadius;
00256 
00257     while ( dwCurX <= dwCurY ) {
00258         dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
00259         dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
00260         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, 
00261                                     dwX + dwCurX - dwXmin, 1 ,color);
00262         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, 
00263                                 dwY+dwCurY, dwX + dwCurX - dwXmin, 1,
00264                         color );
00265         dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
00266         dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
00267         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, dwYmin, 
00268                                 dwX + dwCurY -dwXmin , 1, color );
00269         LCDD_DrawRectangleWithFill(pCanvasBuffer, dwXmin, 
00270                                 dwY + dwCurX, dwX+dwCurY - dwXmin, 1,
00271                         color  );
00272         if ( d < 0 ) {
00273             d += (dwCurX << 2) + 6;
00274         } else {
00275             d += ((dwCurX - dwCurY) << 2) + 10;
00276             dwCurY--;
00277         }
00278         dwCurX++;
00279     }
00280 
00281     return 0;
00282 }
00283 
00284 /**
00285  * \brief Draws a string inside a LCD buffer, at the given coordinates.
00286  *
00287  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00288  * \param x        X-coordinate of string top-left corner.
00289  * \param y        Y-coordinate of string top-left corner.
00290  * \param pString  String to display.
00291  * \param color    String color.
00292  */
00293 void LCDD_DrawString( uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, 
00294                      const uint8_t *pString, uint32_t color )
00295 {
00296     uint32_t xorg = x;
00297 
00298     while ( *pString != 0 ) {
00299         if ( *pString == '\n' ) {
00300             y += gFont.height + 2;
00301             x = xorg;
00302         } else {
00303             LCDD_DrawChar(pCanvasBuffer, x, y, *pString, color );
00304             x += gFont.width + 2;
00305         }
00306         pString++;
00307     }
00308 }
00309 
00310 /**
00311  * \brief Returns the width & height in pixels that a string will occupy on the 
00312  * screen if drawn using LCDD_DrawString.
00313  *
00314  * \param pString  String.
00315  * \param pWidth   Pointer for storing the string width (optional).
00316  * \param pHeight  Pointer for storing the string height (optional).
00317  *
00318  * \return String width in pixels.
00319  */
00320 void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth,
00321                 uint32_t *pHeight )
00322 {
00323     uint32_t width = 0;
00324     uint32_t height = gFont.height;
00325 
00326     while ( *pString != 0 ) {
00327         if ( *pString == '\n' ) {
00328             height += gFont.height + 2;
00329         } else {
00330             width += gFont.width + 2;
00331         }
00332         pString++;
00333     }
00334 
00335     if ( width > 0 ) {
00336         width -= 2;
00337     }
00338 
00339     if ( pWidth != NULL ) {
00340         *pWidth = width;
00341     }
00342 
00343     if ( pHeight != NULL ) {
00344         *pHeight = height;
00345     }
00346 }
00347 
00348 
00349 /*
00350  * \brief Performs a bit-block transfer of the color data corresponding to a 
00351  * rectangle of pixels from the given source context into destination context.
00352  *
00353  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00354  * \param dst_x   X-coordinate of source rectangle.
00355  * \param dst_y   Y-coordinate of source rectangle.
00356  * \param dst_w   Rectangle width in pixels of source rectangle.
00357  * \param dst_h   Rectangle height in pixels of source rectangle.
00358  * \param src     Pointer to the source device context.
00359  * \param src_x   X-coordinate of destination rectangle.
00360  * \param src_y   Y-coordinate of destination rectangle.
00361  * \param src_w   Rectangle width in pixels of destination rectangle.
00362  * \param src_h   Rectangle height in pixels of destination rectangle.
00363  */
00364 void LCDD_BitBlt( uint16_t* pCanvasBuffer, uint32_t dst_x,uint32_t dst_y,uint32_t dst_w,uint32_t dst_h,
00365                  const LcdColor_t *src,
00366                  uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)
00367 {
00368     uint32_t row,col;
00369     uint32_t src_row,src_col;
00370     //assert(gpCanvasBuffer!=NULL);
00371     
00372     src_h = src_h;
00373     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00374         sBGR *p_buf = gpCanvasBuffer;
00375         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00376         //it'd better change to a DMA transfer
00377         SCB_CleanInvalidateDCache();
00378         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00379             for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {
00380                 p_buf[row * gwCanvasMaxWidth+col].r = src[src_row*src_w + src_col]&0xFF;
00381                 p_buf[row * gwCanvasMaxWidth+col].g = src[src_row*src_w + src_col]>>8;
00382                 p_buf[row * gwCanvasMaxWidth+col].b = src[src_row*src_w + src_col]>>16;
00383             }
00384             memory_barrier()
00385         }
00386         memory_barrier()
00387     } else {
00388         uint16_t *p_buf = gpCanvasBuffer;
00389         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00390         //it'd better change to a DMA transfer
00391         SCB_CleanInvalidateDCache();
00392         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00393             for(src_col = src_x, col = dst_x; col < dst_w; col++,src_col++) {
00394                 p_buf[row * gwCanvasMaxWidth+col] = src[src_row*src_w + src_col];
00395             }
00396         }
00397         memory_barrier()
00398     }
00399 }
00400 
00401 
00402 /*
00403  * \brief Performs a bit-block transfer of the color data corresponding to a 
00404  * rectangle of pixels from the given source context into destination context.
00405  *
00406  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00407  * \param dst_x   X-coordinate of source rectangle.
00408  * \param dst_y   Y-coordinate of source rectangle.
00409  * \param dst_w   Rectangle width in pixels of source rectangle.
00410  * \param dst_h   Rectangle height in pixels of source rectangle.
00411  * \param src     Pointer to the source device context.
00412  * \param src_x   X-coordinate of destination rectangle.
00413  * \param src_y   Y-coordinate of destination rectangle.
00414  * \param src_w   Rectangle width in pixels of destination rectangle.
00415  * \param src_h   Rectangle height in pixels of destination rectangle.
00416  * \param alpha   alpha value.
00417  */
00418 void LCDD_BitBltAlphaBlend(uint16_t* pCanvasBuffer,
00419                         uint32_t dst_x,
00420                         uint32_t dst_y,
00421                         uint32_t dst_w,
00422                         uint32_t dst_h,
00423                         const LcdColor_t *src,
00424                         uint32_t src_x,
00425                         uint32_t src_y,
00426                         uint32_t src_w,
00427                         uint32_t src_h,
00428                         uint32_t alpha)
00429 {
00430     uint32_t row,col;
00431     uint32_t src_row,src_col;
00432     uint32_t w,h;
00433     uint32_t dst_row;
00434     uint32_t r,g,b;
00435     
00436     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00437         sBGR *p_buf = gpCanvasBuffer;
00438         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00439 
00440         //it'd better change to a DMA transfer
00441         SCB_CleanInvalidateDCache();
00442         for(src_row = src_y,row = dst_y; row < dst_h; row++,src_row++) {
00443             for(src_col = src_x,col = dst_x; col < dst_w; col++,src_col++) {
00444                 p_buf[row *dst_w +col].r = src[src_row*src_w + src_col]&0xFF;
00445                 p_buf[row *dst_w +col].g = src[src_row*src_w + src_col]>>8;
00446                 p_buf[row *dst_w +col].b = src[src_row*src_w + src_col]>>16;
00447             }
00448         }
00449         memory_barrier()
00450     } else {
00451         uint16_t *p_buf = gpCanvasBuffer;
00452         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00453         w = src_x + src_w;
00454         h = src_y + src_h;
00455         dst_row = dst_y;
00456         p_buf += (dst_row*dst_w + dst_x);
00457         src += src_y*w + src_x;
00458         SCB_CleanInvalidateDCache();
00459         for(src_row = src_y; src_row < h; src_row++,dst_row++) {
00460             for(src_col = src_x; src_col < w; src_col++){
00461                 r = (p_buf[src_col] >> 11) * (255 - alpha) / 255 + 
00462                         (src[src_col] >> 11) * alpha / 255;
00463                 if(r > 0x1F) r = 0x1F;
00464                 g = ((p_buf[src_col] >> 5) & 0x3F) * (255 - alpha) / 255 + 
00465                         ((src[src_col] >> 5) & 0x3f) * alpha / 255;
00466                 if(g > 0x3F) g = 0x3F;
00467                 b = ((p_buf[src_col]) & 0x1F) * (255 - alpha) / 255 
00468                         + ((src[src_col]) & 0x1f) * alpha / 255;
00469                 if(b > 0x1F) b = 0x1F;   
00470                 p_buf[src_col] = ((r & 0x1F) << 11)|((g & 0x3F) << 5)|( b & 0x1F);
00471             }
00472             p_buf += dst_w;
00473             src += w;
00474         }
00475         memory_barrier()
00476     }
00477 }
00478 
00479 /*
00480  * \brief Draw a raw image at given position on LCD.
00481  *
00482  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00483  * \param dwX       X-coordinate of image start.
00484  * \param dwY       Y-coordinate of image start.
00485  * \param pImage    Image buffer.
00486  * \param width     Image width.
00487  * \param height    Image height.
00488  */
00489  void LCDD_DrawImage(uint16_t* pCanvasBuffer, uint32_t dwX, uint32_t dwY, 
00490                     const LcdColor_t *pImage, uint32_t dwWidth, uint32_t dwHeight )
00491 {
00492     /* Determine the refresh window area */
00493     /* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
00494     //CheckBoxCoordinates(&dwX, &dwY, &dwWidth, &dwHeight);
00495 
00496     LCDD_BitBlt(pCanvasBuffer, dwX, dwY, dwWidth, dwHeight,
00497                 pImage, 0, 0, dwWidth - dwX, dwHeight - dwY);
00498 }
00499 
00500 /**
00501  * \brief Draw a pixel on LCD of given color.
00502  *
00503  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00504  * \param x  X-coordinate of pixel.
00505  * \param y  Y-coordinate of pixel.
00506  * \param color  Pixel color.
00507  */
00508 void LCDD_DrawPixel(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, uint32_t color )
00509 {
00510     //assert(gpCanvasBuffer!=NULL);
00511     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00512         sBGR *p_buf = gpCanvasBuffer;
00513         if(pCanvasBuffer != NULL) p_buf = (sBGR *)((uint8_t*)pCanvasBuffer);
00514         if(NULL == p_buf){
00515             LCDD_SetPixelColor(x, y, color);
00516             return;
00517         }
00518         p_buf += y * gwCanvasMaxWidth;
00519         p_buf += x;
00520         p_buf->b = color&0xFF;
00521         p_buf->g = color>>8;
00522         p_buf->r = color>>16;
00523         p_buf++;
00524         memory_barrier()
00525     } else {
00526         uint16_t *p_buf = gpCanvasBuffer;
00527         if(pCanvasBuffer != NULL) p_buf = pCanvasBuffer;
00528         p_buf += y * gwCanvasMaxWidth;
00529         p_buf += x;
00530         *p_buf = (uint16_t)color;
00531     }
00532 }
00533 
00534 /*
00535  * \brief Draw a line on LCD, horizontal and vertical line are supported.
00536  *
00537  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00538  * \param dwX1   X-coordinate of line start.
00539  * \param dwY1   Y-coordinate of line start.
00540  * \param dwX2   X-coordinate of line end.
00541  * \param dwY2   Y-coordinate of line end.
00542  * \param color  Pixel color.
00543  */
00544 void LCDD_DrawLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, 
00545                 uint32_t dwX2, uint32_t dwY2 , uint32_t color )
00546 {
00547     if (( dwY1 == dwY2 ) || (dwX1 == dwX2)) {
00548         //LCDD_DrawRectangleWithFill( dwX1, dwY1, dwX2, dwY2, color );
00549         LCDD_DrawStraightLine(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2, color );
00550     } else {
00551         LCDD_DrawLineBresenham(pCanvasBuffer, dwX1, dwY1, dwX2, dwY2 , color);
00552     }
00553 }
00554 
00555 void LCDD_DrawStraightLine(uint16_t* pCanvasBuffer, uint32_t dwX1, uint32_t dwY1, 
00556                         uint32_t dwX2, uint32_t dwY2 , uint32_t color )
00557 {
00558     uint32_t x,y;
00559     uint32_t tmp;
00560 
00561     if(dwY1 > dwY2)
00562     {
00563         tmp = dwY1;
00564         dwY1 = dwY2;
00565         dwY2 = tmp;
00566     }
00567     if(dwX1 > dwX2)
00568     {
00569         tmp = dwX1;
00570         dwX1 = dwX2;
00571         dwX2 = tmp;
00572     }
00573     for(y = dwY1; y<=dwY2; y++)
00574     {
00575         for(x=dwX1;x<=dwX2;x++)
00576         {
00577             LCDD_DrawPixel(pCanvasBuffer,  x , y , color);
00578         }
00579     }
00580 }
00581 
00582 /*
00583  * \brief Draw a line on LCD, which is not horizontal or vertical.
00584  *
00585  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00586  * \param dwX1    X-coordinate of line start.
00587  * \param dwY1    Y-coordinate of line start.
00588  * \param dwX2    X-coordinate of line end.
00589  * \param dwY2    Y-coordinate of line end.
00590  * \param color   pixel color.
00591  */
00592 uint32_t LCDD_DrawLineBresenham(uint16_t* pCanvasBuffer, uint32_t dwX1, 
00593                 uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 , uint32_t color)
00594 {
00595     int dx, dy;
00596     int i;
00597     int xinc, yinc, cumul;
00598     int x, y;
00599 
00600     x = dwX1;
00601     y = dwY1;
00602     dx = dwX2 - dwX1;
00603     dy = dwY2 - dwY1;
00604 
00605     xinc = ( dx > 0 ) ? 1 : -1;
00606     yinc = ( dy > 0 ) ? 1 : -1;
00607     dx = ( dx > 0 ) ? dx : -dx;
00608     dy = ( dy > 0 ) ? dy : -dy;
00609 
00610     LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00611 
00612     if ( dx > dy ) {
00613         cumul = dx / 2;
00614         for ( i = 1; i <= dx; i++ ) {
00615             x += xinc;
00616             cumul += dy;
00617 
00618             if ( cumul >= dx ) {
00619                 cumul -= dx;
00620                 y += yinc;
00621             }
00622             LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00623         }
00624     } else {
00625         cumul = dy / 2;
00626         for ( i = 1; i <= dy; i++ ) {
00627             y += yinc;
00628             cumul += dx;
00629 
00630             if ( cumul >= dy ) {
00631                 cumul -= dy;
00632                 x += xinc;
00633             }
00634             LCDD_DrawPixel(pCanvasBuffer, x , y , color);
00635         }
00636     }
00637 
00638     return 0;
00639 }
00640 
00641 /*
00642  * \brief Draws a rectangle on LCD, at the given coordinates.
00643  *
00644  * \param pCanvasBuffer Pointer to dedicate canvas buffer.
00645  * \param x      X-coordinate of upper-left rectangle corner.
00646  * \param y      Y-coordinate of upper-left rectangle corner.
00647  * \param width  Rectangle width in pixels.
00648  * \param height Rectangle height in pixels.
00649  * \param color  Rectangle color.
00650  */
00651 void LCDD_DrawRectangle(uint16_t* pCanvasBuffer, uint32_t x, uint32_t y, 
00652                     uint32_t width, uint32_t height, uint32_t color )
00653 {
00654     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, width, 1, color);
00655     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y, 1, height, color);
00656 
00657     LCDD_DrawRectangleWithFill(pCanvasBuffer, x + width , y, 1, height, color);
00658     LCDD_DrawRectangleWithFill(pCanvasBuffer, x, y + height, width, 1, color);
00659 }
00660 
00661 /*
00662  * \brief Set buffer for pCanvas.
00663  *
00664  * \param pCanvasBuffer  Pointer of external buffer.
00665  * \param wBufferSize   Size of buffer.
00666  */
00667 void LCDD_SetCavasBuffer( void* pCanvasBuffer, uint32_t wBufferSize)
00668 {
00669     if (ili9488_lcdMode == ILI9488_SPIMODE) {
00670         gpCanvasBuffer = (sBGR*)pCanvasBuffer;
00671         gwCanvasBufferSize = wBufferSize;
00672     } else {
00673         gpCanvasBuffer = (uint16_t*)pCanvasBuffer;
00674         gwCanvasBufferSize = wBufferSize;
00675     }
00676 }
00677 
00678 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines