Deleted Adafruit Llgo

Dependents:   GPS_OLED_HelloWorld WIZwiki-REST-io_v101 WIZwiki-REST-io_v102 WIZwiki-REST-io_v103

Fork of Adafruit_GFX by DongEun Koak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_GFX.cpp Source File

Adafruit_GFX.cpp

00001 /***********************************
00002 This is a our graphics core library, for all our displays. 
00003 We'll be adapting all the
00004 existing libaries to use this core to make updating, support 
00005 and upgrading easier!
00006 
00007 Adafruit invests time and resources providing this open source code, 
00008 please support Adafruit and open-source hardware by purchasing 
00009 products from Adafruit!
00010 
00011 Written by Limor Fried/Ladyada  for Adafruit Industries.  
00012 BSD license, check license.txt for more information
00013 All text above must be included in any redistribution
00014 ****************************************/
00015 
00016 /*
00017  *  Modified by Neal Horman 7/14/2012 for use in mbed
00018  */
00019 
00020 #include "mbed.h"
00021 
00022 #include "Adafruit_GFX.h"
00023 #include "glcdfont.h"
00024 
00025 #if defined(GFX_WANT_ABSTRACTS)
00026 // draw a circle outline
00027 void Adafruit_GFX::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
00028 {
00029     int16_t f = 1 - r;
00030     int16_t ddF_x = 1;
00031     int16_t ddF_y = -2 * r;
00032     int16_t x = 0;
00033     int16_t y = r;
00034     
00035     drawPixel(x0, y0+r, color);
00036     drawPixel(x0, y0-r, color);
00037     drawPixel(x0+r, y0, color);
00038     drawPixel(x0-r, y0, color);
00039     
00040     while (x<y)
00041     {
00042         if (f >= 0)
00043         {
00044             y--;
00045             ddF_y += 2;
00046             f += ddF_y;
00047         }
00048         x++;
00049         ddF_x += 2;
00050         f += ddF_x;
00051         
00052         drawPixel(x0 + x, y0 + y, color);
00053         drawPixel(x0 - x, y0 + y, color);
00054         drawPixel(x0 + x, y0 - y, color);
00055         drawPixel(x0 - x, y0 - y, color);
00056         drawPixel(x0 + y, y0 + x, color);
00057         drawPixel(x0 - y, y0 + x, color);
00058         drawPixel(x0 + y, y0 - x, color);
00059         drawPixel(x0 - y, y0 - x, color);
00060     }
00061 }
00062 
00063 void Adafruit_GFX::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color)
00064 {
00065     int16_t f     = 1 - r;
00066     int16_t ddF_x = 1;
00067     int16_t ddF_y = -2 * r;
00068     int16_t x     = 0;
00069     int16_t y     = r;
00070     
00071     while (x<y)
00072     {
00073         if (f >= 0)
00074         {
00075             y--;
00076             ddF_y += 2;
00077             f += ddF_y;
00078         }
00079         x++;
00080         ddF_x += 2;
00081         f += ddF_x;
00082         
00083         if (cornername & 0x4)
00084         {
00085             drawPixel(x0 + x, y0 + y, color);
00086             drawPixel(x0 + y, y0 + x, color);
00087         } 
00088 
00089         if (cornername & 0x2)
00090         {
00091             drawPixel(x0 + x, y0 - y, color);
00092             drawPixel(x0 + y, y0 - x, color);
00093         }
00094 
00095         if (cornername & 0x8)
00096         {
00097             drawPixel(x0 - y, y0 + x, color);
00098             drawPixel(x0 - x, y0 + y, color);
00099         }
00100         
00101         if (cornername & 0x1)
00102         {
00103             drawPixel(x0 - y, y0 - x, color);
00104             drawPixel(x0 - x, y0 - y, color);
00105         }
00106     }
00107 }
00108 
00109 void Adafruit_GFX::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
00110 {
00111     drawFastVLine(x0, y0-r, 2*r+1, color);
00112     fillCircleHelper(x0, y0, r, 3, 0, color);
00113 }
00114 
00115 // used to do circles and roundrects!
00116 void Adafruit_GFX::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color)
00117 {
00118     int16_t f     = 1 - r;
00119     int16_t ddF_x = 1;
00120     int16_t ddF_y = -2 * r;
00121     int16_t x     = 0;
00122     int16_t y     = r;
00123     
00124     while (x<y)
00125     {
00126         if (f >= 0)
00127         {
00128             y--;
00129             ddF_y += 2;
00130             f += ddF_y;
00131         }
00132         x++;
00133         ddF_x += 2;
00134         f += ddF_x;
00135         
00136         if (cornername & 0x1)
00137         {
00138             drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
00139             drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
00140         }
00141 
00142         if (cornername & 0x2)
00143         {
00144             drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
00145             drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
00146         }
00147     }
00148 }
00149 #endif
00150 
00151 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT)
00152 // bresenham's algorithm - thx wikpedia
00153 void Adafruit_GFX::drawLine(int16_t x0, int16_t y0,  int16_t x1, int16_t y1, uint16_t color)
00154 {
00155     int16_t steep = abs(y1 - y0) > abs(x1 - x0);
00156     
00157     if (steep)
00158     {
00159         swap(x0, y0);
00160         swap(x1, y1);
00161     }
00162     
00163     if (x0 > x1)
00164     {
00165         swap(x0, x1);
00166         swap(y0, y1);
00167     }
00168     
00169     int16_t dx, dy;
00170     dx = x1 - x0;
00171     dy = abs(y1 - y0);
00172     
00173     int16_t err = dx / 2;
00174     int16_t ystep;
00175     
00176     if (y0 < y1)
00177         ystep = 1;
00178     else
00179         ystep = -1;
00180     
00181     for (; x0<=x1; x0++)
00182     {
00183         if (steep)
00184             drawPixel(y0, x0, color);
00185         else
00186             drawPixel(x0, y0, color);
00187 
00188         err -= dy;
00189         if (err < 0)
00190         {
00191             y0 += ystep;
00192             err += dx;
00193         }
00194     }
00195 }
00196 
00197 void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
00198 {
00199     // stupidest version - update in subclasses if desired!
00200     drawLine(x, y, x, y+h-1, color);
00201 }
00202 
00203 void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
00204 {
00205     // stupidest version - update in subclasses if desired!
00206     for (int16_t i=x; i<x+w; i++)
00207         drawFastVLine(i, y, h, color); 
00208 }
00209 #endif
00210 
00211 #if defined(GFX_WANT_ABSTRACTS)
00212 // draw a rectangle
00213 void Adafruit_GFX::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
00214 {
00215     drawFastHLine(x, y, w, color);
00216     drawFastHLine(x, y+h-1, w, color);
00217     drawFastVLine(x, y, h, color);
00218     drawFastVLine(x+w-1, y, h, color);
00219 }
00220 
00221 void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
00222 {
00223     // stupidest version - update in subclasses if desired!
00224     drawLine(x, y, x+w-1, y, color);
00225 }
00226 
00227 void Adafruit_GFX::fillScreen(uint16_t color)
00228 {
00229     fillRect(0, 0, _width, _height, color);
00230 }
00231 
00232 // draw a rounded rectangle!
00233 void Adafruit_GFX::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
00234 {
00235     // smarter version
00236     drawFastHLine(x+r  , y    , w-2*r, color); // Top
00237     drawFastHLine(x+r  , y+h-1, w-2*r, color); // Bottom
00238     drawFastVLine(  x    , y+r  , h-2*r, color); // Left
00239     drawFastVLine(  x+w-1, y+r  , h-2*r, color); // Right
00240     // draw four corners
00241     drawCircleHelper(x+r    , y+r    , r, 1, color);
00242     drawCircleHelper(x+w-r-1, y+r    , r, 2, color);
00243     drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
00244     drawCircleHelper(x+r    , y+h-r-1, r, 8, color);
00245 }
00246 
00247 // fill a rounded rectangle!
00248 void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
00249 {
00250     // smarter version
00251     fillRect(x+r, y, w-2*r, h, color);
00252     
00253     // draw four corners
00254     fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
00255     fillCircleHelper(x+r    , y+r, r, 2, h-2*r-1, color);
00256 }
00257 
00258 // draw a triangle!
00259 void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
00260 {
00261     drawLine(x0, y0, x1, y1, color);
00262     drawLine(x1, y1, x2, y2, color);
00263     drawLine(x2, y2, x0, y0, color);
00264 }
00265 
00266 // fill a triangle!
00267 void Adafruit_GFX::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
00268 {
00269     int16_t a, b, y, last;
00270     
00271     // Sort coordinates by Y order (y2 >= y1 >= y0)
00272     if (y0 > y1)
00273         swap(y0, y1); swap(x0, x1);
00274 
00275     if (y1 > y2)
00276         swap(y2, y1); swap(x2, x1);
00277 
00278     if (y0 > y1)
00279         swap(y0, y1); swap(x0, x1);
00280 
00281     
00282     if(y0 == y2)
00283     { // Handle awkward all-on-same-line case as its own thing
00284         a = b = x0;
00285         if(x1 < a)
00286             a = x1;
00287         else if(x1 > b)
00288             b = x1;
00289             
00290         if(x2 < a)
00291             a = x2;
00292         else if(x2 > b) b = x2;
00293             drawFastHLine(a, y0, b-a+1, color);
00294         return;
00295     }
00296 
00297     int16_t
00298         dx01 = x1 - x0,
00299         dy01 = y1 - y0,
00300         dx02 = x2 - x0,
00301         dy02 = y2 - y0,
00302         dx12 = x2 - x1,
00303         dy12 = y2 - y1,
00304         sa   = 0,
00305         sb   = 0;
00306 
00307     // For upper part of triangle, find scanline crossings for segments
00308     // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
00309     // is included here (and second loop will be skipped, avoiding a /0
00310     // error there), otherwise scanline y1 is skipped here and handled
00311     // in the second loop...which also avoids a /0 error here if y0=y1
00312     // (flat-topped triangle).
00313     if(y1 == y2)
00314         last = y1;   // Include y1 scanline
00315     else
00316         last = y1-1; // Skip it
00317 
00318     for(y=y0; y<=last; y++)
00319     {
00320         a   = x0 + sa / dy01;
00321         b   = x0 + sb / dy02;
00322         sa += dx01;
00323         sb += dx02;
00324         /* longhand:
00325         a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
00326         b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00327         */
00328         if(a > b)
00329             swap(a,b);
00330         drawFastHLine(a, y, b-a+1, color);
00331     }
00332 
00333     // For lower part of triangle, find scanline crossings for segments
00334     // 0-2 and 1-2.  This loop is skipped if y1=y2.
00335     sa = dx12 * (y - y1);
00336     sb = dx02 * (y - y0);
00337     for(; y<=y2; y++)
00338     {
00339         a   = x1 + sa / dy12;
00340         b   = x0 + sb / dy02;
00341         sa += dx12;
00342         sb += dx02;
00343         /* longhand:
00344         a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
00345         b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
00346         */
00347         if(a > b)
00348             swap(a,b);
00349         drawFastHLine(a, y, b-a+1, color);
00350     }
00351 }
00352 
00353 void Adafruit_GFX::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
00354 {
00355     for (int16_t j=0; j<h; j++)
00356     {
00357         for (int16_t i=0; i<w; i++ )
00358         {
00359             if (bitmap[i + (j/8)*w] & _BV(j%8))
00360                 drawPixel(x+i, y+j, color);
00361         }
00362     }
00363 }
00364 #endif
00365 
00366 size_t Adafruit_GFX::writeChar(uint8_t c)
00367 {
00368     if (c == '\n')
00369     {
00370         cursor_y += textsize*8;
00371         cursor_x = 0;
00372     }
00373     else if (c == '\r')
00374         cursor_x = 0;
00375     else
00376     {
00377         drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize);
00378         cursor_x += textsize*6;
00379         if (wrap && (cursor_x > (_width - textsize*6)))
00380         {
00381             cursor_y += textsize*8;
00382             cursor_x = 0;
00383         }
00384     }
00385     return 1;
00386 }
00387 
00388 // draw a character
00389 void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
00390 {
00391     if(
00392         (x >= _width) || // Clip right
00393         (y >= _height) || // Clip bottom
00394         ((x + 5 * size - 1) < 0) || // Clip left
00395         ((y + 8 * size - 1) < 0) // Clip top
00396         )
00397     return;
00398     
00399     for (int8_t i=0; i<6; i++ )
00400     {
00401         uint8_t line = 0;
00402 
00403         if (i == 5) 
00404             line = 0x0;
00405         else 
00406             line = font[(c*5)+i];
00407             
00408         for (int8_t j = 0; j<8; j++)
00409         {
00410             if (line & 0x1)
00411             {
00412 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT)
00413                 if (size == 1) // default size
00414                     drawPixel(x+i, y+j, color);
00415                 else // big size
00416                     fillRect(x+(i*size), y+(j*size), size, size, color);
00417 #else
00418                 drawPixel(x+i, y+j, color);
00419 #endif
00420             }
00421             else if (bg != color)
00422             {
00423 #if defined(GFX_WANT_ABSTRACTS) || defined(GFX_SIZEABLE_TEXT)
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 #else
00429                 drawPixel(x+i, y+j, bg);
00430 #endif
00431             }
00432             line >>= 1;
00433         }
00434     }
00435 }
00436 
00437 void Adafruit_GFX::setRotation(uint8_t x)
00438 {
00439     x %= 4;  // cant be higher than 3
00440     rotation = x;
00441     switch (x)
00442     {
00443         case 0:
00444         case 2:
00445             _width = _rawWidth;
00446             _height = _rawHeight;
00447             break;
00448         case 1:
00449         case 3:
00450             _width = _rawHeight;
00451             _height = _rawWidth;
00452             break;
00453     }
00454 }