SAMV71 Xplained Ultra Software Package 1.5

lcd_draw.c

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