Testanto funções Display

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ADA_GFX_kbv.cpp Source File

ADA_GFX_kbv.cpp

00001 
00002 // link:
00003 // https://os.mbed.com/users/davidprentice/code/Nucleo_dir_L152//file/d88d2ad55fac/ADA_GFX_kbv/ADA_GFX_kbv.cpp/
00004 // Committer: davidprentice
00005 // Date:      19 months ago
00006 // 2021-04-21
00007 //
00008 // ADA_GFX_kbv.cpp
00009 //
00010 /*
00011 This is the core graphics library for all our displays, providing a common
00012 set of graphics primitives (points, lines, circles, etc.).  It needs to be
00013 paired with a hardware-specific library for each display device we carry
00014 (to handle the lower-level functions).
00015  
00016 Adafruit invests time and resources providing this open source code, please
00017 support Adafruit & open-source hardware by purchasing products from Adafruit!
00018  
00019 Copyright (c) 2013 Adafruit Industries.  All rights reserved.
00020  
00021 Redistribution and use in source and binary forms, with or without
00022 modification, are permitted provided that the following conditions are met:
00023  
00024 - Redistributions of source code must retain the above copyright notice,
00025   this list of conditions and the following disclaimer.
00026 - Redistributions in binary form must reproduce the above copyright notice,
00027   this list of conditions and the following disclaimer in the documentation
00028   and/or other materials provided with the distribution.
00029  
00030 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00031 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00034 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00035 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00036 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00037 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00038 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00039 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00040 POSSIBILITY OF SUCH DAMAGE.
00041 */
00042  
00043 #include "ADA_GFX_kbv.h"
00044 #ifdef __AVR__
00045  #include <avr/pgmspace.h>
00046 #else
00047  #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
00048  #define PROGMEM
00049 #endif
00050 #include "glcdfont.inc"
00051  
00052 Adafruit_GFX::Adafruit_GFX(int16_t w, int16_t h):
00053   WIDTH(w), HEIGHT(h)
00054 {
00055   _width    = WIDTH;
00056   _height   = HEIGHT;
00057   rotation  = 0;
00058   cursor_y  = cursor_x    = 0;
00059   textsize  = 1;
00060   textcolor = textbgcolor = 0xFFFF;
00061   wrap      = true;
00062 }
00063  
00064 // Draw a circle outline
00065 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r,
00066     uint16_t color) {
00067   int16_t f = 1 - r;
00068   int16_t ddF_x = 1;
00069   int16_t ddF_y = -2 * r;
00070   int16_t x = 0;
00071   int16_t y = r;
00072  
00073   drawPixel(x0  , y0+r, color);
00074   drawPixel(x0  , y0-r, color);
00075   drawPixel(x0+r, y0  , color);
00076   drawPixel(x0-r, y0  , color);
00077  
00078   while (x<y) {
00079     if (f >= 0) {
00080       y--;
00081       ddF_y += 2;
00082       f += ddF_y;
00083     }
00084     x++;
00085     ddF_x += 2;
00086     f += ddF_x;
00087   
00088     drawPixel(x0 + x, y0 + y, color);
00089     drawPixel(x0 - x, y0 + y, color);
00090     drawPixel(x0 + x, y0 - y, color);
00091     drawPixel(x0 - x, y0 - y, color);
00092     drawPixel(x0 + y, y0 + x, color);
00093     drawPixel(x0 - y, y0 + x, color);
00094     drawPixel(x0 + y, y0 - x, color);
00095     drawPixel(x0 - y, y0 - x, color);
00096   }
00097 }
00098  
00099 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0,
00100                int16_t r, uint8_t cornername, uint16_t color) {
00101   int16_t f     = 1 - r;
00102   int16_t ddF_x = 1;
00103   int16_t ddF_y = -2 * r;
00104   int16_t x     = 0;
00105   int16_t y     = r;
00106  
00107   while (x<y) {
00108     if (f >= 0) {
00109       y--;
00110       ddF_y += 2;
00111       f     += ddF_y;
00112     }
00113     x++;
00114     ddF_x += 2;
00115     f     += ddF_x;
00116     if (cornername & 0x4) {
00117       drawPixel(x0 + x, y0 + y, color);
00118       drawPixel(x0 + y, y0 + x, color);
00119     } 
00120     if (cornername & 0x2) {
00121       drawPixel(x0 + x, y0 - y, color);
00122       drawPixel(x0 + y, y0 - x, color);
00123     }
00124     if (cornername & 0x8) {
00125       drawPixel(x0 - y, y0 + x, color);
00126       drawPixel(x0 - x, y0 + y, color);
00127     }
00128     if (cornername & 0x1) {
00129       drawPixel(x0 - y, y0 - x, color);
00130       drawPixel(x0 - x, y0 - y, color);
00131     }
00132   }
00133 }
00134  
00135 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r,
00136                   uint16_t color) {
00137   drawFastVLine(x0, y0-r, 2*r+1, color);
00138   fillCircleHelper(x0, y0, r, 3, 0, color);
00139 }
00140  
00141 // Used to do circles and roundrects
00142 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
00143     uint8_t cornername, int16_t delta, uint16_t color) {
00144  
00145   int16_t f     = 1 - r;
00146   int16_t ddF_x = 1;
00147   int16_t ddF_y = -2 * r;
00148   int16_t x     = 0;
00149   int16_t y     = r;
00150  
00151   while (x<y) {
00152     if (f >= 0) {
00153       y--;
00154       ddF_y += 2;
00155       f     += ddF_y;
00156     }
00157     x++;
00158     ddF_x += 2;
00159     f     += ddF_x;
00160  
00161     if (cornername & 0x1) {
00162       drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
00163       drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
00164     }
00165     if (cornername & 0x2) {
00166       drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
00167       drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
00168     }
00169   }
00170 }
00171  
00172 // Bresenham's algorithm - thx wikpedia
00173 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,
00174                 int16_t x1, int16_t y1,
00175                 uint16_t color) {
00176   int16_t steep = abs(y1 - y0) > abs(x1 - x0);
00177   if (steep) {
00178     swap(x0, y0);
00179     swap(x1, y1);
00180   }
00181  
00182   if (x0 > x1) {
00183     swap(x0, x1);
00184     swap(y0, y1);
00185   }
00186  
00187   int16_t dx, dy;
00188   dx = x1 - x0;
00189   dy = abs(y1 - y0);
00190  
00191   int16_t err = dx / 2;
00192   int16_t ystep;
00193  
00194   if (y0 < y1) {
00195     ystep = 1;
00196   } else {
00197     ystep = -1;
00198   }
00199  
00200   for (; x0<=x1; x0++) {
00201     if (steep) {
00202       drawPixel(y0, x0, color);
00203     } else {
00204       drawPixel(x0, y0, color);
00205     }
00206     err -= dy;
00207     if (err < 0) {
00208       y0 += ystep;
00209       err += dx;
00210     }
00211   }
00212 }
00213  
00214 // Draw a rectangle
00215 void Adafruit_GFX::drawRect(int16_t x, int16_t y,
00216                 int16_t w, int16_t h,
00217                 uint16_t color) {
00218   drawFastHLine(x, y, w, color);
00219   drawFastHLine(x, y+h-1, w, color);
00220   drawFastVLine(x, y, h, color);
00221   drawFastVLine(x+w-1, y, h, color);
00222 }
00223  
00224 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y,
00225                  int16_t h, uint16_t color) {
00226   // Update in subclasses if desired!
00227   drawLine(x, y, x, y+h-1, color);
00228 }
00229  
00230 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y,
00231                  int16_t w, uint16_t color) {
00232   // Update in subclasses if desired!
00233   drawLine(x, y, x+w-1, y, color);
00234 }
00235  
00236 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
00237                 uint16_t color) {
00238   // Update in subclasses if desired!
00239   for (int16_t i=x; i<x+w; i++) {
00240     drawFastVLine(i, y, h, color);
00241   }
00242 }
00243  
00244 void Adafruit_GFX::fillScreen(uint16_t color) {
00245   fillRect(0, 0, _width, _height, color);
00246 }
00247  
00248 // Draw a rounded rectangle
00249 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w,
00250   int16_t h, int16_t r, uint16_t color) {
00251   // smarter version
00252   drawFastHLine(x+r  , y    , w-2*r, color); // Top
00253   drawFastHLine(x+r  , y+h-1, w-2*r, color); // Bottom
00254   drawFastVLine(x    , y+r  , h-2*r, color); // Left
00255   drawFastVLine(x+w-1, y+r  , h-2*r, color); // Right
00256   // draw four corners
00257   drawCircleHelper(x+r    , y+r    , r, 1, color);
00258   drawCircleHelper(x+w-r-1, y+r    , r, 2, color);
00259   drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
00260   drawCircleHelper(x+r    , y+h-r-1, r, 8, color);
00261 }
00262  
00263 // Fill a rounded rectangle
00264 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
00265                  int16_t h, int16_t r, uint16_t color) {
00266   // smarter version
00267   fillRect(x+r, y, w-2*r, h, color);
00268  
00269   // draw four corners
00270   fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
00271   fillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, color);
00272 }
00273  
00274 // Draw a triangle
00275 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
00276                 int16_t x1, int16_t y1,
00277                 int16_t x2, int16_t y2, uint16_t color) {
00278   drawLine(x0, y0, x1, y1, color);
00279   drawLine(x1, y1, x2, y2, color);
00280   drawLine(x2, y2, x0, y0, color);
00281 }
00282  
00283 // Fill a triangle
00284 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0,
00285                   int16_t x1, int16_t y1,
00286                   int16_t x2, int16_t y2, uint16_t color) {
00287  
00288   int16_t a, b, y, last;
00289  
00290   // Sort coordinates by Y order (y2 >= y1 >= y0)
00291   if (y0 > y1) {
00292     swap(y0, y1); swap(x0, x1);
00293   }
00294   if (y1 > y2) {
00295     swap(y2, y1); swap(x2, x1);
00296   }
00297   if (y0 > y1) {
00298     swap(y0, y1); swap(x0, x1);
00299   }
00300  
00301   if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
00302     a = b = x0;
00303     if(x1 < a)      a = x1;
00304     else if(x1 > b) b = x1;
00305     if(x2 < a)      a = x2;
00306     else if(x2 > b) b = x2;
00307     drawFastHLine(a, y0, b-a+1, color);
00308     return;
00309   }
00310  
00311   int16_t
00312     dx01 = x1 - x0,
00313     dy01 = y1 - y0,
00314     dx02 = x2 - x0,
00315     dy02 = y2 - y0,
00316     dx12 = x2 - x1,
00317     dy12 = y2 - y1;
00318   int32_t                    //.kbv larger triangles overflow with int16_t
00319     sa   = 0,
00320     sb   = 0;
00321  
00322   // For upper part of triangle, find scanline crossings for segments
00323   // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
00324   // is included here (and second loop will be skipped, avoiding a /0
00325   // error there), otherwise scanline y1 is skipped here and handled
00326   // in the second loop...which also avoids a /0 error here if y0=y1
00327   // (flat-topped triangle).
00328   if(y1 == y2) last = y1;   // Include y1 scanline
00329   else         last = y1-1; // Skip it
00330  
00331   for(y=y0; y<=last; y++) {
00332     a   = x0 + sa / dy01;
00333     b   = x0 + sb / dy02;
00334     sa += dx01;
00335     sb += dx02;
00336     /* longhand:
00337     a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
00338     b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00339     */
00340     if(a > b) swap(a,b);
00341     drawFastHLine(a, y, b-a+1, color);
00342   }
00343  
00344   // For lower part of triangle, find scanline crossings for segments
00345   // 0-2 and 1-2.  This loop is skipped if y1=y2.
00346   sa = dx12 * (y - y1);
00347   sb = dx02 * (y - y0);
00348   for(; y<=y2; y++) {
00349     a   = x1 + sa / dy12;
00350     b   = x0 + sb / dy02;
00351     sa += dx12;
00352     sb += dx02;
00353     /* longhand:
00354     a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
00355     b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00356     */
00357     if(a > b) swap(a,b);
00358     drawFastHLine(a, y, b-a+1, color);
00359   }
00360 }
00361  
00362 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y,
00363                   const uint8_t *bitmap, int16_t w, int16_t h,
00364                   uint16_t color) {
00365  
00366   int16_t i, j, byteWidth = (w + 7) / 8;
00367  
00368   for(j=0; j<h; j++) {
00369     for(i=0; i<w; i++ ) {
00370       if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) {
00371     drawPixel(x+i, y+j, color);
00372       }
00373     }
00374   }
00375 }
00376  
00377 #if defined(ARDUINO) && ARDUINO < 100
00378 virtual void Adafruit_GFX::write(uint8_t c) {
00379 #else
00380 size_t Adafruit_GFX::write(uint8_t c) {
00381 #endif
00382   if (c == '\n') {
00383     cursor_y += textsize*8;
00384     cursor_x  = 0;
00385   } else if (c == '\r') {
00386     // skip em
00387   } else {
00388     drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
00389     cursor_x += textsize*6;
00390     if (wrap && (cursor_x > (_width - textsize*6))) {
00391       cursor_y += textsize*8;
00392       cursor_x = 0;
00393     }
00394   }
00395 #if !(defined(ARDUINO) && ARDUINO < 100)
00396   return 1;
00397 #endif
00398 }
00399  
00400 // Draw a character
00401 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
00402                 uint16_t color, uint16_t bg, uint8_t size) {
00403  
00404   if((x >= _width)            || // Clip right
00405      (y >= _height)           || // Clip bottom
00406      ((x + 6 * size - 1) < 0) || // Clip left
00407      ((y + 8 * size - 1) < 0))   // Clip top
00408     return;
00409  
00410   for (int8_t i=0; i<6; i++ ) {
00411     uint8_t line;
00412     if (i == 5) 
00413       line = 0x0;
00414     else 
00415       line = pgm_read_byte(font+(c*5)+i);
00416     for (int8_t j = 0; j<8; j++) {
00417       if (line & 0x1) {
00418         if (size == 1) // default size
00419           drawPixel(x+i, y+j, color);
00420         else {  // big size
00421           fillRect(x+(i*size), y+(j*size), size, size, color);
00422         } 
00423       } else if (bg != color) {
00424         if (size == 1) // default size
00425           drawPixel(x+i, y+j, bg);
00426         else {  // big size
00427           fillRect(x+i*size, y+j*size, size, size, bg);
00428         }
00429       }
00430       line >>= 1;
00431     }
00432   }
00433 }
00434  
00435 void Adafruit_GFX::setCursor(int16_t x, int16_t y) {
00436   cursor_x = x;
00437   cursor_y = y;
00438 }
00439  
00440 void Adafruit_GFX::setTextSize(uint8_t s) {
00441   textsize = (s > 0) ? s : 1;
00442 }
00443  
00444 void Adafruit_GFX::setTextColor(uint16_t c) {
00445   // For 'transparent' background, we'll set the bg 
00446   // to the same as fg instead of using a flag
00447   textcolor = textbgcolor = c;
00448 }
00449  
00450 void Adafruit_GFX::setTextColor(uint16_t c, uint16_t b) {
00451   textcolor   = c;
00452   textbgcolor = b; 
00453 }
00454  
00455 void Adafruit_GFX::setTextWrap(boolean w) {
00456   wrap = w;
00457 }
00458  
00459 uint8_t Adafruit_GFX::getRotation(void) {
00460   return rotation;
00461 }
00462  
00463 void Adafruit_GFX::setRotation(uint8_t x) {
00464   rotation = (x & 3);
00465   switch(rotation) {
00466    case 0:
00467    case 2:
00468     _width  = WIDTH;
00469     _height = HEIGHT;
00470     break;
00471    case 1:
00472    case 3:
00473     _width  = HEIGHT;
00474     _height = WIDTH;
00475     break;
00476   }
00477 }
00478  
00479 // Return the size of the display (per current rotation)
00480 int16_t Adafruit_GFX::width(void) {
00481   return _width;
00482 }
00483  
00484 int16_t Adafruit_GFX::height(void) {
00485   return _height;
00486 }
00487  
00488 void Adafruit_GFX::invertDisplay(boolean i) {
00489   // Do nothing, must be subclassed if supported
00490 }
00491  
00492 // this looks the most convenient method of all.  i.e. forget about print() and println()
00493 // and could be part of ADA_GFX_kbv.cpp.  possibly overwritten by later classes.
00494 // possibly use global buffer rather than stack.
00495 #include <stdarg.h>
00496 int  Adafruit_GFX::printf(const char* format, ...)
00497 {
00498     char buffer[80];
00499     va_list args;
00500     va_start (args, format);
00501     vsnprintf (buffer, 80, format, args);
00502     for (char *p = buffer; *p; p++) write(*p);
00503     va_end (args);
00504     return strlen(buffer);
00505 }
00506